SQLite:具有 30 多个列的四个表的完全外部连接
SQLite: full outer join with four tables with 30+ columns
这个问题是对这个的扩展
我想用 SQLite 连接四个不同的表,它们只有两列相同。但是,假设有 30 多列,即不仅仅是列 a - h。请看下面的例子
表 1:
a b lon lat
---------------
22 33 11 22
表 2:
c d lon lat
---------------
1 2 44 45
表3
e f lon lat
-----------------------
NULL NULL 100 101
表4
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 |
+------+------+------+------+------+------+------+------+-----+-----+
- 问题:如果我不仅有 a 到 h 的列,还有 a 到 z 的列,即表 1、表 2、表 3 和表 4 中的许多列怎么办 -> 这将非常耗时并且结构会如果我必须在我的 sql 语句中将 NULL 写成 [letter],请明确
- @zarruq 提供了巨大的帮助,他建议在那种情况下我可以只使用 `UNION ALL` 然后使用 `PIVOT` 将列转换为行
- 但是,我不确定该怎么做。而且,我 100% 不知道他的意思。
- 编辑:SQLite 不支持数据透视:还有其他建议吗?
使用 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 |
+------+------+------+------+------+------+------+------+-----+-----+
P.S。请注意,上面的查询是针对 sql-Server
,因此您可能需要为 dbms
.
调整一下
当您有 30 多个列时,我认为没有特别巧妙的方法可以做到这一点。以下是我能做的最好的,使用嵌套 CTE 实现 full outer joins, then using coalesce
以选择第一个非空值 lat/lon.
仍然需要枚举顶部 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
)
这个问题是对这个
我想用 SQLite 连接四个不同的表,它们只有两列相同。但是,假设有 30 多列,即不仅仅是列 a - h。请看下面的例子
表 1:
a b lon lat
---------------
22 33 11 22
表 2:
c d lon lat
---------------
1 2 44 45
表3
e f lon lat
-----------------------
NULL NULL 100 101
表4
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 |
+------+------+------+------+------+------+------+------+-----+-----+
- 问题:如果我不仅有 a 到 h 的列,还有 a 到 z 的列,即表 1、表 2、表 3 和表 4 中的许多列怎么办 -> 这将非常耗时并且结构会如果我必须在我的 sql 语句中将 NULL 写成 [letter],请明确
- @zarruq 提供了巨大的帮助,他建议在那种情况下我可以只使用 `UNION ALL` 然后使用 `PIVOT` 将列转换为行
- 但是,我不确定该怎么做。而且,我 100% 不知道他的意思。
- 编辑:SQLite 不支持数据透视:还有其他建议吗?
使用 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 |
+------+------+------+------+------+------+------+------+-----+-----+
P.S。请注意,上面的查询是针对 sql-Server
,因此您可能需要为 dbms
.
当您有 30 多个列时,我认为没有特别巧妙的方法可以做到这一点。以下是我能做的最好的,使用嵌套 CTE 实现 full outer joins, then using coalesce
以选择第一个非空值 lat/lon.
仍然需要枚举顶部 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
)