2016-02-02 84 views
0

Employee表:SQL IN()被包括NULL值

+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+ 
| 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()運算符是如何在最終結果集中返回的?我認爲沒有什麼東西等於空。

+1

運行「SELECT superior_emp_id FROM employee」查詢,您將看到該結果集將包含(1 ,1,3,4,4 ...等)。 – algor

+0

@algor是對的。你應該告訴我們你期望看到什麼。目前,你對子查詢做什麼的假設似乎是錯誤的。 –

回答

2

如果子查詢SELECT superior_emp_id FROM employee邁克爾史密斯返回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。但這不是你的例子中發生的事情。

N.B.爲避免混淆,最好避免在IN子句的任何一邊使用NULL記錄,如@Donal

+1

我想通了,你在回答中說的是我如何計算出來的。採取了一些思考的想法。謝謝! –

1
SELECT superior_emp_id FROM employee 

返回[NULL, 1, 3, 4, 6, 10, 13, 16]。我在這裏看不到問題。

+0

然後再仔細觀察! 'IN'與'''使用相同的ANSI規則來比較'NULL':http://stackoverflow.com/questions/6362112/in-clause-with-null-or-is-null#comment7448343_6362112 MySQL不會允許非ANSI比較,並且'in'實際上只是對列表中的每個元素執行迭代比較,因此即使列表包含'null',null也不會列入列表中。 –

+0

@underscore_d真,但'1'(邁克爾的emp_id)在'[NULL,1,3,4,6,10,13,16]' – Arth

+0

...但是OP與Michael的'superior_emp_id'進行比較,_is_ 'null'。 –

1

查看SQL Server中的ANSI_NULLS設置。

T-SQL支持的擴展,其允許比較 運營商針對空值進行比較時返回TRUE或FALSE。 該選項通過設置ANSI_NULLS OFF來激活。當ANSI_NULLS是 OFF時,如ColumnA = NULL的比較在列A 包含空值時返回TRUE,而在列A包含除NULL之外的某些值 時返回FALSE。

摘自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); 
+0

感謝您的提示。但是我的問題是爲什麼'IN'運算符與NULL比較成功,因爲除了IS NOT NULL和IS NULL運算符之外,沒有什麼可以與NULL進行比較。 –

+0

@RobertRocha好的,我已經更新了我的答案。 – Donal

+0

好吧,好吧,我明白了。 –