如何使not in子句null安全?

sd2nnvve  于 2021-06-25  发布在  Mysql
关注(0)|答案(2)|浏览(590)

这是我的表格结构:

// questions_and_answers
+----+-------------------+------+----------+
| id |       body        | type | related  |
+----+-------------------+------+----------+
| 1  | a question        | 0    | NULL     |
| 2  | my answer         | 1    | 1        |
| 3  | another answer    | 1    | 1        |
| 4  | another question  | 0    | NULL     |
| 5  | another answer    | 1    | 4        |
| 6  | another answer    | 1    | 1        |  
+----+-------------------+------+----------+
-- type column: it is either 0 for questions and 1 for answers.
-- related column: it is either null for questions and "the id of its question" for answers

现在我需要选择所有未回答的问题。我的问题是:

SELECT *
FROM questions_and_answers AS qa
WHERE
  type = 0 -- just questions
  AND
  qa.id NOT IN (SELECT q.related FROM qanda q WHERE q.type <> 0) -- unanswered ones

它运行良好,一切正常。
我的问题是什么?当有这样的行时,我的查询不匹配任何行:

| 7  | another answer    | 1    | NULL      |

看到了吗?价值 type1 ,所以这是一个答案。但它的价值 relatedNULL ,所以它没有指向任何问题。一般来说,这一行没有意义,但可能有时会发生(当一个问题被删除,我们设置 related 它的答案 null ). 在这种情况下,我的查询结果是“未选择行”。
为什么?在这种情况下,我怎样才能保证我的查询是安全的呢(安全==忽略它们,仍然匹配未回答的问题)

9cbw7uwe

9cbw7uwe1#

您只能像这样从第二个select中删除所有这些记录(related=null)

SELECT *
FROM qa
WHERE type = 0 -- just questions
  AND id NOT IN 
    (SELECT related 
       FROM qa
       WHERE type <> 0
         AND related IS NOT NULL
    )
xxb16uws

xxb16uws2#

使用 not exists :

where not exists (select 1 from quanda q where q.related = qa.id and q.type <> 0)

我强烈建议你不要使用 not in 使用子查询——特别是因为 NULL 问题。只是使用 not exists . 使用索引进行优化也更容易。

相关问题