sql - on-clause 中的 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。
这背后的原因是什么?或者我怎么能用谷歌搜索这个话题?感谢。
解决方案
这是您的第一个查询,结构略有不同:
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
并且d
是left join
.
如何left join
工作?连接产生第一个表中的每一行以及第二个表中与每个第一个表行匹配的每一行。如果第二个表中没有行,则NULL
返回值。然后这个集合被where
子句过滤。
这是什么意思?如果on
子句返回false
or null
,则仍返回第一个表中的行。让我重复一遍: 无论子句的结果如何,都会返回第一个表中的所有行。直接后果:对 a 子句中第一个表的过滤器无效(好吧,它们将返回第二个表中列的值)。on
on
left join
NULL
所以,所有这些过滤都应该在where
子句中。
推荐阅读
- wordpress - 在 laravel Passport 中使用授权码授予登录第三方应用程序不起作用
- ssl - Kubernetes Ingress SSL 证书无效
- jquery - 如何从 jsTree 隐藏特定节点
- uproot - 如何使用锯齿状数组获得与 root_numpy root2array() 输出相同的 uproot.iterate() 输出
- python - 带有 Python3 和 C 扩展的 Docker 使用 popen() 导致分段错误
- c# - 带有 EF Core 的 MS SQL Server '引入 FOREIGN KEY 约束可能会导致循环或多个级联路径' 与 Delete Behavior SetNull
- swift - swift/coreml 实现的 LSTM 维度问题
- node.js - 数组为空,添加for循环后无数据
- python - 网页抓取python中打印网址的问题
- android - 向用户实时交付 OSMDroid Mapnik 压缩图块集的最佳方法