SQL IN()包含NULL值

时间:2016-02-02 16:16:57

标签: mysql subquery

员工表:

+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+
| 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。

3 个答案:

答案 0 :(得分:2)

  

如果子查询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。

迈克尔的emp_id为1并且返回了他的行,因为1 = NULL OR 1 = 1 ....可以写为FALSE OR TRUE ....,返回TRUE

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

N.B。为避免混淆,最好避免在IN子句的任何一侧使用NULL记录,如@Donal所引用的那样

答案 1 :(得分:1)

SELECT superior_emp_id FROM employee

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

答案 2 :(得分:1)

查看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);