具有NULL值的IN运算符caluse似乎有效

时间:2018-02-11 23:20:45

标签: mysql sql

我有一个'#at-expanded-menu-host'表:

employee

如果我这样做

+--------+----------+-----------+------------+----------+-----------------+---------+--------------------+--------------------+
| 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 | +--------+---------+-----------+--------------------+ 列中有NULL个值。

如果superior_emp_id运算符等同于IN,为什么此查询不会失败或出现错误?

2 个答案:

答案 0 :(得分:4)

它运作得很好。您可能会混淆innot in

如果您运行not in,那么您将无法获得任何结果。为什么?好吧,考虑1 not in (2, 3)。评估结果为真。是显而易见的。

然后2 not in (2, 3)。评估结果为假。就像它应该的那样。

但是。 。 。这两个怎么样:

  • 2 not in (2, 3, NULL)
  • 1 not in (2, 3, NULL)

第一个是假的,因为" 2"确实在列表中。第二是。 。 。好吧,NULL不是一个值。这意味着"未知"。所以,可能" 1"或者是其他东西。因此,它评估为NULLNULL中的where被视为与false相同。

您可以解决这个问题,但in不会发生这种情况。例如,在您的情况下,NULL or 1=1的计算结果为真。

出于这个原因,我强烈建议始终使用not exists而不是not in使用子查询。一个必然结果是我建议使用exists而不是in,但这样才能使用exists的习惯。

答案 1 :(得分:0)

x = NULL谓词计算结果为UNKNOWN

关于OR运算符:

TRUE或UNKNOWN = TRUE

FALSE或UNKNOWN = UNKNOWN(在WHERE子句中被视为FALSE)

请参阅:https://en.wikipedia.org/wiki/Three-valued_logic