【问题标题】:SQL IN () is including NULL valuesSQL IN () 包含 NULL 值
【发布时间】:2016-05-11 13:17:05
【问题描述】:

员工表:

+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+
| emp_id | fname    | lname     | start_date | end_date | superior_emp_id | dept_id | title              | assigned_branch_id |
+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+
|      1 | Michael  | Smith     | 2005-06-22 | NULL     |            NULL |       3 | President          |                  1 |
|      2 | Susan    | Barker    | 2006-09-12 | NULL     |               1 |       3 | Vice President     |                  1 |
|      3 | Robert   | Tyler     | 2005-02-09 | NULL     |               1 |       3 | Treasurer          |                  1 |
|      4 | Susan    | Hawthorne | 2006-04-24 | NULL     |               3 |       1 | Operations Manager |                  1 |
|      5 | John     | Gooding   | 2007-11-14 | NULL     |               4 |       2 | Loan Manager       |                  1 |
|      6 | Helen    | Fleming   | 2008-03-17 | NULL     |               4 |       1 | Head Teller        |                  1 |
|      7 | Chris    | Tucker    | 2008-09-15 | NULL     |               6 |       1 | Teller             |                  1 |
|      8 | Sarah    | Parker    | 2006-12-02 | NULL     |               6 |       1 | Teller             |                  1 |
|      9 | Jane     | Grossman  | 2006-05-03 | NULL     |               6 |       1 | Teller             |                  1 |
|     10 | Paula    | Roberts   | 2006-07-27 | NULL     |               4 |       1 | Head Teller        |                  2 |
|     11 | Thomas   | Ziegler   | 2004-10-23 | NULL     |              10 |       1 | Teller             |                  2 |
|     12 | Samantha | Jameson   | 2007-01-08 | NULL     |              10 |       1 | Teller             |                  2 |
|     13 | John     | Blake     | 2004-05-11 | NULL     |               4 |       1 | Head Teller        |                  3 |
|     14 | Cindy    | Mason     | 2006-08-09 | NULL     |              13 |       1 | Teller             |                  3 |
|     15 | Frank    | Portman   | 2007-04-01 | NULL     |              13 |       1 | Teller             |                  3 |
|     16 | Theresa  | Markham   | 2005-03-15 | NULL     |               4 |       1 | Head Teller        |                  4 |
|     17 | Beth     | Fowler    | 2006-06-29 | NULL     |              16 |       1 | Teller             |                  4 |
|     18 | Rick     | Tulman    | 2006-12-12 | NULL     |              16 |       1 | Teller             |                  4 |
+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+

查询:

SELECT emp_id, fname, lname, title
FROM employee
WHERE emp_id IN (SELECT superior_emp_id FROM employee);

查询结果:

+--------+---------+-----------+--------------------+
| emp_id | fname   | lname     | title              |
+--------+---------+-----------+--------------------+
|      1 | Michael | Smith     | President          |
|      3 | Robert  | Tyler     | Treasurer          |
|      4 | Susan   | Hawthorne | Operations Manager |
|      6 | Helen   | Fleming   | Head Teller        |
|     10 | Paula   | Roberts   | Head Teller        |
|     13 | John    | Blake     | Head Teller        |
|     16 | Theresa | Markham   | Head Teller        |
+--------+---------+-----------+--------------------+

子查询结果:

+-----------------+
| superior_emp_id |
+-----------------+
|            NULL |
|               1 |
|               1 |
|               3 |
|               4 |
|               4 |
|               4 |
|               4 |
|               4 |
|               6 |
|               6 |
|               6 |
|              10 |
|              10 |
|              13 |
|              13 |
|              16 |
|              16 |
+-----------------+

如果子查询 SELECT superior_emp_id FROM employee 为 Michael Smith 返回 NULL,IN() 运算符如何在最终结果集中返回它?我认为没有什么等于 null。

【问题讨论】:

  • 运行“SELECT Superior_emp_id FROM employee”查询,您会看到该结果集将包含 (1,1,3,4,4... 等)。
  • @algor 是对的。您应该告诉我们您预期会看到什么。目前,您对该子查询会做什么的假设似乎是错误的。

标签: mysql subquery


【解决方案1】:

如果子查询 SELECT superior_emp_id FROM employee 为 Michael Smith 返回 NULL,那么 IN() 运算符如何在最终结果集中返回它?

简短的回答,它没有。

子查询有效地为每一行返回整个superior_emp_ids [NULL, 1, 1, 3, 3, 4, 4, 6, 6, 6, 4, 10, 10, 4, 13, 13, 4, 16, 16]集。

您的 WHERE 子句测试每个 emp_id 以查看它是否在此集合中。 IN 基本上是一系列相等的比较 OR'd 在一起。

Michael 的 emp_id 为 1 并且他的行被返回,因为 1 = NULL OR 1 = 1 .... 可以写成 FALSE OR TRUE .... 返回 TRUE

您假设 NULL 不等于任何内容(包括 NULL)是正确的,因此WHERE NULL IN (NULL, 1, FALSE, ... anything you like ...) 将返回 FALSE。但这不是您的示例中发生的情况。

注意为了避免任何混淆,最好在@Donal 引用的可能的情况下避免在 IN 子句的任一侧出现 NULL 记录

【讨论】:

  • 我想通了,你在回答中所说的正是我想通的。想了想。谢谢!
【解决方案2】:
SELECT superior_emp_id FROM employee

返回[NULL, 1, 3, 4, 6, 10, 13, 16]。我在这里没有看到问题。

【讨论】:

  • 然后仔细看! IN 使用与 NULL 相同的 ANSI 规则与 = 进行比较:stackoverflow.com/questions/6362112/… MySQL 不允许非 ANSI 比较,in 实际上只是对列表中的每个元素执行迭代比较,所以null 绝不是 in 列表,即使该列表包含 null
  • @underscore_d 是的,但 1(Michael 的 emp_id)在 [NULL, 1, 3, 4, 6, 10, 13, 16]
  • ...但是 OP 正在与 Michael 的 superior_emp_id 进行比较, null
  • @underscore_d WHERE emp_id IN (SELECT superior_emp_id FROM employee) .. 直接来自问题
  • 是的,我看错了。我认为所有关于 nulls 的答案虽然具有教育意义,但都是红鲱鱼,而且 OP 根本不了解子 select 将要做什么。
【解决方案3】:

查看 SQL Server 中的 ANSI_NULLS 设置。

Transact-SQL 支持允许比较的扩展 运算符在与空值进行比较时返回 TRUE 或 FALSE。 此选项通过设置 ANSI_NULLS OFF 来激活。当 ANSI_NULLS 是 OFF,ColumnA = NULL 等比较在 ColumnA 时返回 TRUE 当 ColumnA 包含某个值时,包含一个空值和 FALSE 除了NULL。

取自here

如果您不想要 NULL 值,则需要在子查询中添加 WHERE 子句。例如:

SELECT emp_id, fname, lname, title
FROM employee
WHERE emp_id IN (SELECT superior_emp_id FROM employee WHERE superior_emp_id IS NOT NULL);

【讨论】:

  • 感谢您的提示。但我的问题是为什么 IN 运算符成功与 NULL 进行比较,因为除了 IS NOT NULL 和 IS NULL 运算符之外,没有任何东西可以与 NULL 进行比较。
  • @RobertRocha 好的,抱歉,我以为问题是针对 SQL Server 的。使用 MySQL - 看起来您无法关闭 ANSI_NULLS。见这里:stackoverflow.com/questions/2747279/something-about-ansi-nulls
  • @RobertRocha 在任何情况下,您都应该避免在 IN 子句中使用 NULL - 请参阅此处:boundlessjourney.wordpress.com/2013/05/11/…
猜你喜欢
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 2010-11-03
  • 2018-02-09
  • 2020-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多