SQLite3 - 为什么 LEFT JOIN 与其他 RDBMS 不同?

SQLite3 - Why LEFT JOIN differs from other RDBMSes?

例如,两个表有很多(或只有一个)关系。作家和书籍。例如,我们要检查这是否是一个没有任何书籍的新作者。

SELECT authors.id
FROM authors
LEFT JOIN books ON authors.id = books.author_id AND books.id IS NULL

这将在任何 RDBMS 中正常工作:MySQL、PostgreSQL、SQL 服务器,也许是 Oracle,但在 SQLite3 中不行。在 SQLite3 最后一部分需要移动到 WHERE:

SELECT authors.id
FROM authors
LEFT JOIN books ON authors.id = books.author_id
WHERE books.id IS NULL

才能正常工作。为什么?

你说 ON 子句中的条件版本进行任何过滤是不正确的。例如,here 是 MySQL SQL Fiddle 表示将条件放在 ON 子句 return 的两行中。

这是获得没有书的作者的正确方法,使用 LEFT JOIN:

SELECT authors.id
FROM authors LEFT JOIN
     books
     ON authors.id = books.author_id
WHERE books.id IS NULL;

这会过滤掉有书的作者,留下没有书的作者。 LEFT JOIN 的逻辑很简单:保留第一个 table 中的所有行,而不管 ON 条件的计算结果是真、假还是 NULL.

将条件放在 ON 子句中具有不同的逻辑。它将 return 所有 作者。没有过滤。

我依稀记得有些数据库的某些版本有一个错误,就是这样一个常量表达式被当作过滤子句。然而,这是不正确的。您所认为的 "exception" 是正确的,应该适用于任何数据库。