子句内部的SQLite约束不起作用

时间:2018-10-06 09:05:06

标签: sql sqlite

SQL#1

select doc.doc_id, doc.content, link, words.words 
from doc left join words 
on doc.doc_id = words.doc_id and words.words = "foo" and doc.doc_id < 1538766632412
where doc.content like "%foo%" and words.words is null
order by doc.doc_id desc limit 10

SQL#2

select doc.doc_id, doc.content, link, words.words 
from doc left join words 
on doc.doc_id = words.doc_id and words.words = "foo"
where doc.content like "%foo%" and words.words is null  and doc.doc_id < 1538766632412
order by doc.doc_id desc limit 10

SQL#1的结果未考虑“ doc.doc_id <1538766632412”。但约束在SQL#2中确实有效。而且我在SQLite文档中发现,“如果存在ON子句,则笛卡尔乘积的每一行都会将布尔表达式作为布尔表达式来评估ON表达式。从该数据集中仅将表达式评估为true的行包括在内。”根据DOC,该表达式应在SQL#1中的此类记录上返回false。

这是什么原因?或者我该如何搜索这个主题? 谢谢。

1 个答案:

答案 0 :(得分:2)

这是您的第一个查询,结构有所不同:

select d.doc_id, d.content, ?.link, w.words 
from doc d left join
     words w
     on d.doc_id = w.doc_id and w.words = 'foo' and
        d.doc_id < 1538766632412
where d.content like '%foo%; and w.words is null
order by d.doc_id desc
limit 10;

我看到的是d.doc_id < 1538766632412子句中on的条件-dleft join中的第一张表。

left join的工作方式是什么?联接产生第一张表中的每一行以及第二张表中与第一张表的每一行匹配的每一行。如果第二个表中没有行,则返回NULL值。然后,该集合由where子句过滤。

这是什么意思?如果on子句返回falsenull,则仍返回第一个表中的行。让我重复一遍:无论on子句的结果如何, 都将返回第一个表中的所有行。直接结果:on子句中第一个表上的过滤器对于left join无效(嗯,它们将为第二个表中的列返回NULL值)。

因此,所有此类过滤都应在where子句中。