繁体   English   中英

即使不匹配where条件,Sql Subquery IN子句也会返回所有行

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM