与SQLite完全合作

时间:2009-12-17 17:19:55

标签: sql sqlite join full-outer-join

SQLite只有INNER和LEFT JOIN。

有没有办法与SQLite进行完全外连接?

4 个答案:

答案 0 :(得分:91)

是的,请参阅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

答案 1 :(得分:5)

根据Jonathan Leffler的评论,这里是Mark Byers的另一个答案:

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示例,请参阅here

答案 2 :(得分:0)

对于人们,寻找模拟独特的完全外连接的答案: 由于 SQLite 既不支持完全外连接,也不支持右连接,我不得不模拟一个不同的完全外连接/反向内连接(不管你怎么称呼它)。 以下维恩图显示了预期的输出:

Venn Diagram: Distinct Full Outer 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 版本测试

答案 3 :(得分:0)

我会迟到的投入我的 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 个名称列,name1 和 name2,它们可能有一个空值或相等的值。我们想要的是将 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 个左连接和一个联合的不足之处,这是我目前所看到的推荐的。