这是我的表结构:
// 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 |
请参阅? type
的值为1
,因此它是一个答案。但related
的值为NULL
,因此它没有指出任何问题。一般情况下,该行没有任何意义,但有时可能会发生(当问题被删除并且我们将related
的答案设置为null
时)。在这种情况下,我的查询结果是“no row selected”。
为什么呢?如何在这种情况下使我的查询安全? (安全==忽略它们并仍然匹配未回答的问题)
答案 0 :(得分:1)
使用not exists
:
where not exists (select 1 from quanda q where q.related = qa.id and q.type <> 0)
我强烈建议您永远不要将not in
与子查询一起使用 - 特别是因为NULL
问题。只需使用not exists
即可。使用索引进行优化也更容易。
答案 1 :(得分:1)
您必须只从第二个SELECT中删除所有这些记录(相关= 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
)