sql - 使用单个连接子句连接多个表(sqlite)
问题描述
所以我正在学习 SQL(sqlite 风格)并查看sqlite JOIN-clause 文档,我认为这两个语句是有效的:
SELECT *
FROM table1
JOIN (table2, table3) USING (id);
SELECT *
FROM table1
JOIN table2 USING (id)
JOIN table3 USING (id)
(甚至,但这无关紧要:
SELECT *
FROM table1
JOIN (table 2 JOIN table3 USING id) USING id
)
现在我在关于JOIN
子句的 SO 问题中看到了很多第二个(链式连接),但很少看到第一个(分组表查询)。对于非简化情况,这两个查询都在 SQLiteStudio 中执行。
此处基于此代码提供了一个最小示例
CREATE TABLE table1 (
id INTEGER PRIMARY KEY,
field1 TEXT
)
WITHOUT ROWID;
CREATE TABLE table2 (
id INTEGER PRIMARY KEY,
field2 TEXT
)
WITHOUT ROWID;
CREATE TABLE table3 (
id INTEGER PRIMARY KEY,
field3 TEXT
)
WITHOUT ROWID;
INSERT INTO table1 (field1, id)
VALUES ('FOO0', 0),
('FOO1', 1),
('FOO2', 2),
('FOO3', 3);
INSERT INTO table2 (field2, id)
VALUES ('BAR0', 0),
('BAR2', 1),
('BAR3', 3);
INSERT INTO table3 (field3, id)
VALUES ('PIP0', 0),
('PIP1', 1),
('PIP2', 2);
SELECT *
FROM table1
JOIN (table2, table3) USING (id);
SELECT *
FROM table1
JOIN table2 USING (id)
JOIN table3 USING (id);
有人可以解释为什么一个人会使用一个而不是另一个,如果它们对于某些输入数据不等效,请提供一个例子?第一个对我来说当然看起来更干净(至少不那么多余)。
INNER JOIN ON vs WHERE 子句被建议为可能的重复。虽然它涉及,
用作连接运算符,但我觉得问题,尤其是答案更侧重于可读性方面和WHERE
vs的使用JOIN
。我的问题更多的是关于结果的一般有效性和可能的差异(考虑到引起差异的必要输入)。
解决方案
SQLite 不强制执行正确的连接语法。它将连接运算符([INNER] JOIN
,等,甚至是过时的 1980 年代连接语法的逗号)与条件( , )LEFT [OUTER] JOIN
分开。这不好,因为它使连接更容易出错。因此,SQLite 文档对于学习连接来说是一个非常糟糕的参考。(而且 SQLite 本身是一个糟糕的学习系统,因为 DBMS 没有检测到标准的 SQL 连接违规。)ON
USING
坚持 SQL 标准定义的语法(并且永远不要使用逗号分隔的连接):
FROM表 [别名]
((([ INNER ] | [( LEFT | FULL ) [ OUTER ]]) JOIN table [alias] ( ON条件 | USING ( columns ) )) | ( CROSS JOIN table [alias]))
((([ INNER ] | [( LEFT | FULL ) [ OUTER ]]) JOIN table [alias] ( ON条件 | USING ( columns ) )) | ( CROSS JOIN table [alias]))
...
(希望,我做对了 :-) 我也希望这足够可读 :-| 我在这里省略了NATURAL JOIN
和RIGHT [OUTER] JOIN
,因为我根本不建议使用它们。)
因为table
您可以放置一些表名或视图或子查询(后者包括括号,例如(select * from mytable)
)。中的列USING
必须用括号括起来(例如USING (a, b, c)
)。ON
(如果您觉得这更易读,您当然也可以在条件周围使用括号。)
在您的情况下,正确编写的查询将是:
SELECT *
FROM table1
JOIN table2 USING (id)
JOIN table3 USING (id)
或者
SELECT *
FROM table1 t1
JOIN table2 t2 ON t2.id = t1.id
JOIN table3 t3 ON t3.id = t1.id
例如。不过,该示例建议了三个 1:1 相关表。在现实生活中,这些是极其罕见的,一个更典型的例子是
SELECT *
FROM table1 t1
JOIN table2 t2 ON t2.t1_id = t1.id
JOIN table3 t3 ON t3.t2_id = t2.id
推荐阅读
- python - 使用 pdfkit 使用 python 创建 pdf 文件
- android - 让 viewpager2 响应标签点击事件
- google-sheets - QUERY(...) 稍微改变日期时间值
- laravel - 使用 nova-media-library 上传图片并使用 nova-page 显示
- sql - SQL:基于另一个表设置条件值,具有 BETWEEN 日期条件
- android-studio - ARcore可以在不触屏的情况下画线吗?
- python - Python中的向量计算
- dji-sdk - DJI Mobile SDK - 调用 sendVirtualStickFlightControlData 时出错
- sql - 关键字“IF”附近的 SQL 语法不正确
- ios - 如何为两个 UIView 中的 UIIMageView 添加触摸处理程序