[英]Sql Subquery IN clause returns all rows even if not match where condition
如果列'src'='L',我只是过滤名字有的用户
我知道我们可以通过SELECT * from users where src ='L'
执行SELECT * from users where src ='L'
来过滤
但我只是尝试使用子查询SELECT * FROM users WHERE firstname in (SELECT firstname from users where src ='L')
它返回所有 'L' 和 'S' 行
表数据:
create table users (id integer, firstname varchar(100), lastname varchar(100),src varchar(100));
insert into users (id, firstname, lastname,src) values
(1, 'albert', 'einstein','L'),
(2, 'isaac', 'newton','S'),
(3, 'marie', 'curie','L'),
(4, 'isaac', 'newton','L');
理想情况下,两个查询都应该只返回“L”记录。 我不是sql专家 谁能解释一下区别。
但是如果我删除 id 4 那么两个查询都只返回 L 或 S 记录
谢谢
您的子查询返回isaac
作为名字,他实际上有源“L”和“S”的两行。 如果您想获得与子查询相同的结果,那么最好通过 id 列而不是 firstName 将子查询与外部查询连接起来,因为 id 列是唯一的。
SELECT * FROM users WHERE id in (SELECT id from users where src ='L')
我假设您正在尝试学习 SQL。 所以我在这里分享另一种使用exists
而不是in
SELECT * FROM users u WHERE
exists (SELECT 1 from users usr where src ='L' and u.id=usr.id)
DB-Fiddle 中的所有查询:
架构和插入语句:
create table users (id integer, firstname varchar(100), lastname varchar(100),src varchar(100));
insert into users (id, firstname, lastname,src) values
(1, 'albert', 'einstein','L'),
(2, 'isaac', 'newton','S'),
(3, 'marie', 'curie','L'),
(4, 'isaac', 'newton','L');
查询:
SELECT * FROM users WHERE id in (SELECT id from users where src ='L')
输出:
ID | 名 | 姓 | 源文件 |
---|---|---|---|
1 | 艾伯特 | 爱因斯坦 | 升 |
3 | 玛丽 | 居里 | 升 |
4 | 以撒 | 牛顿 | 升 |
查询存在:
SELECT * FROM users u WHERE
exists (SELECT 1 from users usr where src ='L' and u.id=usr.id)
输出:
ID | 名 | 姓 | 源文件 |
---|---|---|---|
1 | 艾伯特 | 爱因斯坦 | 升 |
3 | 玛丽 | 居里 | 升 |
4 | 以撒 | 牛顿 | 升 |
子查询:
SELECT firstname from users where src ='L'
名 |
---|
艾伯特 |
玛丽 |
以撒 |
查询以选择所有行 WHERE FirstName='isaac'
SELECT * FROM users WHERE FirstName='isaac'
输出:
ID | 名 | 姓 | 源文件 |
---|---|---|---|
2 | 以撒 | 牛顿 | 秒 |
4 | 以撒 | 牛顿 | 升 |
db<> 在这里摆弄
第二个查询返回所有名字,其中至少有一个来自src = 'L'
。
第一个只返回src = 'L'
。
这些是不一样的。 名字在表中可以有多个行,其中一些来自 L,一些不是。
子查询返回:
mysql> SELECT firstname from users where src ='L';
+-----------+
| firstname |
+-----------+
| albert |
| marie |
| isaac |
+-----------+
主查询返回该列表中带有名字的所有行。 你有两行以撒,一切正常。
您需要更改逻辑并在主查询中添加src
检查。
我对这个问题的更好理解
Main Query : Select * users
+-----+-----------+----------+-----+
| id | firstname | lastname | src |
+-----+-----------+----------+-----+
| 1 | albert | einstein | L |
| 2 | isaac | newton | S |
| 3 | marie | curie | L |
| 4 | isaac | newton | L |
+-----+-----------+----------+-----+
Sub Query : SELECT firstname from users where src ='L'
+-----+-----------+----------+-----+
| id | firstname | lastname | src |
+-----+-----------+----------+-----+
| 1 | albert | einstein | L |
| |
| 3 | marie | curie | L |
| 4 | isaac | newton | L |
+-----+-----------+----------+-----+
Where Id 2 firstname(isaac) is in Sub Query result Id 4 of firstname,
So Its true to returns all rows
+-----+-----------+----------+-----+
| id | firstname | lastname | src |
+-----+-----------+----------+-----+
| 1 | albert | einstein | L |
| 2 | isaac | newton | S |
| 3 | marie | curie | L |
| 4 | isaac | newton | L |
+-----+-----------+----------+-----+
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.