如何合并 SQLite 中每个 table 的所有公共列

How to union all common columns from every table in SQLite

对于table秒
t1:

C1 C2 C3
1  2  3
4  5  6

table t2:

C1 C2 C4
33 44 55

应该编写什么查询来执行所有公共列的并集,以便结果如下:

C1  C2
1   2
4   5
33  44

重要的是要注意,我不是在为两个 table 寻找解决方案,而是在为数据库中的每个 table 寻找解决方案。数据库是 SQLite

SQLite 不支持动态 sql,所以你最多可以利用它自己的功能来构造一个 SQL 语句来做你想做的事,你可以使用像 Java 或 Python.

这样的编程语言来执行它

这个查询:

WITH tables AS (SELECT name FROM sqlite_master WHERE type = 'table') 
SELECT pti.name col
FROM tables t CROSS JOIN pragma_table_info(t.name) pti
GROUP BY col
HAVING COUNT(*) = (SELECT COUNT(*) FROM tables);

returns 数据库所有 tables 中共有的所有列。

通过使用 GROUP_CONCAT(),您可以获得所有这些列作为逗号分隔的列表,您可以在 SELECT 语句中使用:

WITH tables AS (SELECT name FROM sqlite_master WHERE type = 'table') 
SELECT GROUP_CONCAT(col) columns
FROM (
  SELECT pti.name col
  FROM tables t CROSS JOIN pragma_table_info(t.name) pti
  GROUP BY col
  HAVING COUNT(*) = (SELECT COUNT(*) FROM tables)
);

最后,将关键字 'SELECT''FROM' 以及每个 table 的名称和 GROUP_CONCAT() 再次连接起来,然后 'UNION ALL' (或 'UNION') 作为分隔符构造 sql 语句:

WITH tables AS (SELECT name FROM sqlite_master WHERE type = 'table') 
SELECT GROUP_CONCAT(sql, ' UNION ALL ') sql
FROM ( 
  SELECT 'SELECT ' || 
    (
      SELECT GROUP_CONCAT(col) columns
      FROM (
        SELECT pti.name col
        FROM tables t CROSS JOIN pragma_table_info(t.name) pti
        GROUP BY col
        HAVING COUNT(*) = (SELECT COUNT(*) FROM tables)
      )
    ) || ' FROM ' || name AS sql
  FROM tables
);

这将 return 一个像这样的字符串:

SELECT col1,col2 FROM table1 UNION ALL SELECT col1,col2 FROM table2 UNION ALL SELECT col1,col2 FROM table3

你可以执行。

查看简化的 demo.