SQLite 只有 INNER 和 LEFT JOIN。
有没有办法用 SQLite 进行 FULL OUTER JOIN?
是的,请参阅Wikipedia上的示例。
SELECT employee.*, department.*
FROM employee
LEFT JOIN department
ON employee.DepartmentID = department.DepartmentID
UNION ALL
SELECT employee.*, department.*
FROM department
LEFT JOIN employee
ON employee.DepartmentID = department.DepartmentID
WHERE employee.DepartmentID IS NULL
继 Jonathan Leffler 在 Mark Byers' answer中的评论之后,这里有一个替代答案,它使用UNION
而不是UNION ALL
:
SELECT * FROM table_name_1 LEFT OUTER JOIN table_name_2 ON id_1 = id_2
UNION
SELECT * FROM table_name_2 LEFT OUTER JOIN table_name_1 ON id_1 = id_2
编辑:上面 SQLite 示例的原始来源以及可以找到更多 SQLite 示例的地方是http://sqlite.awardspace.info/syntax/sqlitepg06.htm但似乎该站点现在返回 404 Not Found 错误.
对于人们来说,寻找模拟Distinct Full Outer Join的答案:由于 SQLite 既不支持 Full Outer Join 也不支持 Right Join,我不得不模拟不同的完全外连接/倒置内连接(但是你可以称之为)。下面的维恩图显示了预期的输出:
为了接收这个预期的输出,我结合了两个Left Join子句(这个例子是指两个相同的构建表,但数据部分不同。我只想输出出现在表 A 或表 B 中的数据)。
SELECT A.flightNumber, A.offblockTime, A.airspaceCount, A.departure, A.arrival FROM D2flights A
LEFT JOIN D1flights B
ON A.flightNumber = B.flightNumber
WHERE B.flightNumber IS NULL
UNION
SELECT A.flightNumber, A.offblockTime, A.airspaceCount, A.departure, A.arrival FROM D1flights A
LEFT JOIN D2flights B
ON A.flightNumber = B.flightNumber
WHERE B.flightNumber IS NULL
上面的 SQLite 语句在一个查询中返回预期结果。看来,UNION子句也确实通过flightNumber列对输出进行排序。
该代码已使用 SQLite 版本 3.32.2 进行测试
我迟早会投入我的 2 美分。考虑下面的 2 个简单表 people1 和 people2:
id name age
0 1 teo 59
1 2 niko 57
2 3 maria 54
id name weight
0 1 teo 186
1 2 maria 125
2 3 evi 108
首先,我们创建一个临时视图 v_all,在其中我们使用 UNION 连接两个相反的 LEFT JOINS,如下所示:
CREATE TEMP VIEW v_all AS
SELECT p1.name AS name1, p1.age,
p2.name AS name2, p2.weight
FROM people1 p1
LEFT JOIN people2 AS p2
USING (name)
UNION
SELECT p1.name AS name1, p1.age,
p2.name AS name2, p2.weight
FROM people2 AS p2
LEFT JOIN people1 AS p1
USING (name);
但是,我们最终得到 2 个名称列,名称 1 和名称 2,它们可能具有空值或相等值。我们想要的是将 name1 和 name2 组合在一个列名中。我们可以使用 CASE 查询来做到这一点,如下所示:
SELECT age,weight,
CASE
WHEN name1 IS NULL
THEN name2
WHEN name2 IS NULL
THEN name1
WHEN name1=name2
THEN name1
END name
FROM v_all
我们最终得到:
name weight age
0 evi 108 None
1 maria 125 54
2 niko None 57
3 teo 186 59
当然,您可以将两者结合在一个查询中,而无需创建临时视图。我避免这样做,以强调仅 2 个左连接和一个联合的不足,这是我迄今为止所看到的推荐。