【问题标题】:SQLite: full outer join with four tables with 30+ columnsSQLite:具有 30 列以上的四个表的完全外连接
【发布时间】:2018-05-19 22:07:38
【问题描述】:

这个问题是这个post的扩展
我想用 SQLite 连接四个不同的表,它们只有两列共有。但是,假设有 30 多列,即不仅仅是列 a - h。请看下面的例子

表 1:

a   b   lon lat
---------------
22  33  11  22

表 2:

c   d   lon lat
---------------
1   2   44  45

Table3

e       f       lon lat
-----------------------
NULL    NULL    100 101

Table4

g       h       lon lat
-----------------------
NULL    NULL    200 201

目前的解决方案如下

SELECT a,b,NULL AS c, NULL AS d,NULL AS e, NULL AS f, NULL AS g, NULL AS h,
lon,lat
FROM table1
UNION ALL
SELECT NULL, NULL,c,d,NULL AS e, NULL AS f, NULL AS g, NULL AS h, lon,lat
FROM table2
UNION ALL
SELECT NULL, NULL,NULL,NULL,e,f, NULL AS g, NULL AS h, lon,lat
FROM table3
UNION ALL
SELECT NULL, NULL,NULL,NULL,NULL,NULL,g,h, lon,lat
from table4

结果:

+------+------+------+------+------+------+------+------+-----+-----+
|  a   |  b   |  c   |  d   |  e   |  f   |  g   |  h   | lon | lat |
+------+------+------+------+------+------+------+------+-----+-----+
| 22   | 33   | NULL | NULL | NULL | NULL | NULL | NULL |  11 |  22 |
| NULL | NULL | 1    | 2    | NULL | NULL | NULL | NULL |  44 |  45 |
| NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 100 | 101 |
| NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 200 | 201 |
+------+------+------+------+------+------+------+------+-----+-----+

DEMO

  • 问题:如果我不仅有 a 到 h 列,还有 a 到 z 列,即 table1、table2、table3 和 table4 中的许多列 -> 这将非常耗时且结构不会清楚我是否必须在我的 sql 语句中到处写 NULL 作为 [字母]
  • @zarruq 帮了大忙,他建议在这种情况下,我可以使用 `UNION ALL` 然后使用 `PIVOT` 将列转换为行
  • 但是,我不知道该怎么做。而且,我不知道 100% 他的意思。
  • 编辑:SQLite 不支持数据透视:还有其他建议吗?

【问题讨论】:

    标签: sql sqlite join full-outer-join


    【解决方案1】:

    当您有 30 多列时,我认为没有一种特别巧妙的方法可以做到这一点。以下是我能做的最好的事情,使用嵌套 CTE 实现 full outer joins,然后使用 coalesce 选择第一个非空纬度/经度。

    仍然需要枚举顶部 SELECT 语句中的所有 30 多个字段,但至少不需要 NULL AS ... 的海量列表:

    SELECT 
      a, b, c, d, e, f, g, h,
      coalesce(lat1, lat2, lat3, lat4) AS lat,
      coalesce(lon1, lon2, lon3, lon4) AS lon
      FROM (
        WITH t1_x_t2 AS (
            SELECT t1.*, t2.*, 
            t1.lat AS lat1, t2.lat AS lat2, t1.lon AS lon1, t2.lon AS lon2
            FROM table1 t1 LEFT OUTER JOIN table2 t2 ON 0
          UNION ALL
            SELECT t1.*, t2.*, 
            t1.lat AS lat1, t2.lat AS lat2, t1.lon AS lon1, t2.lon AS lon2
            FROM table2 t2 LEFT OUTER JOIN table1 t1 ON 0
        ), t3_x_t4 AS (
            SELECT t3.*, t4.*, 
            t3.lat AS lat3, t4.lat AS lat4, t3.lon AS lon3, t4.lon AS lon4
            FROM table3 t3 LEFT OUTER JOIN table4 t4 ON 0
          UNION ALL
            SELECT t3.*, t4.*, 
            t3.lat AS lat3, t4.lat AS lat4, t3.lon AS lon3, t4.lon AS lon4
            FROM table4 t4 LEFT OUTER JOIN table3 t3 ON 0
        )
        SELECT t1_x_t2.*, t3_x_t4.* FROM t1_x_t2 LEFT OUTER JOIN t3_x_t4 ON 0
        UNION ALL
        SELECT t1_x_t2.*, t3_x_t4.* FROM t3_x_t4 LEFT OUTER JOIN t1_x_t2 ON 0
    )
    

    【讨论】:

      【解决方案2】:

      使用pivot()(如果您的dbms 支持)导出结果的一种方法可能如下。

      select a,b,c,d,e,f,g,h,lon,lat
      from (
      select 'a' as columnName1, a as val1,'b' as ColumnName2, b as val2, lon,lat
      from table1
      union all
      select 'c',c,'d', d, lon,lat
      from table2
      union all
      select 'e',e,'f', f, lon,lat
      from table3
      union all
      select 'g',g,'h', h, lon,lat
      from table4
      ) t1
      PIVOT (MAX(val1)
            FOR columnName1 IN (a,c,e,g)) as Pivot1
      PIVOT (MAX(val2)
            FOR columnName2 IN (b,d,f,h)) AS Pivot2;
      

      结果:

      +------+------+------+------+------+------+------+------+-----+-----+
      |  a   |  b   |  c   |  d   |  e   |  f   |  g   |  h   | lon | lat |
      +------+------+------+------+------+------+------+------+-----+-----+
      | 22   | 33   | NULL | NULL | NULL | NULL | NULL | NULL |  11 |  22 |
      | NULL | NULL | 1    | 2    | NULL | NULL | NULL | NULL |  44 |  45 |
      | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 100 | 101 |
      | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | 200 | 201 |
      +------+------+------+------+------+------+------+------+-----+-----+
      

      DEMO

      附言请注意,上面的查询是针对sql-Server,所以你可能需要为你的dbms tweek 它。

      【讨论】:

      • SQLite 不支持PIVOT
      • @peterdn 哦,该死的......你有什么想法可以解决这个问题吗?
      • @AndrejCoding 有点像,虽然有点难看——看我的回答。
      猜你喜欢
      • 1970-01-01
      • 2012-09-27
      • 1970-01-01
      • 1970-01-01
      • 2021-02-16
      • 2020-03-30
      • 2015-12-11
      • 1970-01-01
      • 2018-05-01
      相关资源
      最近更新 更多