例如,两个表有很多(或有一个)关系。作者和书籍。例如,我们想检查这是一个没有任何书籍的新作者。
SELECT authors.id
FROM authors
LEFT JOIN books ON authors.id = books.author_id AND books.id IS NULL
这可以在任何RDBMS中正常工作:MySQL,PostgreSQL,SQL Server,也许是Oracle,但不能在SQLite3中。在SQLite3中,最后一部分需要移动到WHERE
:
SELECT authors.id
FROM authors
LEFT JOIN books ON authors.id = books.author_id
WHERE books.id IS NULL
正常工作。为什么呢?
答案 0 :(得分:2)
ON
子句中具有条件的版本进行任何过滤是不正确的。例如,here是一个MySQL SQL小提琴,它表明将条件放在ON
子句中会返回两行。
使用LEFT JOIN
:
SELECT authors.id
FROM authors LEFT JOIN
books
ON authors.id = books.author_id
WHERE books.id IS NULL;
这会过滤掉有书籍的作者,而作者却没有书籍。 LEFT JOIN
的逻辑很简单:将所有行保留在第一个表中,无论ON
条件是否计算为true,false或NULL
。
将条件放在ON
子句中具有不同的逻辑。它将返回所有作者。没有过滤。
我有一个模糊的回忆,一些数据库的某些版本有一个错误,这种常量表达式被视为过滤子句。但是,这是不正确的。你认为什么是"例外"是正确的,应该适用于任何数据库。