在不知道列名的情况下组合任意表

时间:2021-04-18 12:25:57

标签: sql sqlite

我正在寻找一种像这样组合两个表的方法:

<头>
x y
1 2
<头>
x z
3 4
<头>
x y z
1 2 NULLL
3 NULL 4

重要的是,我希望能够组合两个我事先不知道其列名的任意表。因此

SELECT x, y, Null as z FROM t1 
UNION 
SELECT x, Null as y, z FROM t2

即使对这个特定示例做了正确的事情,也不能解决我的问题。

编辑

引发这个问题的问题:

我正在构建一个与数据源通信的库。它必须解析来自数据源的原始数据,并根据接收到的值控制数据源。当然,它还必须存储它接收到的数据。只要原始结果可以转换为映射,它就应该适用于任何数据源。添加新的数据源可以通过编写新的解析器并重写控制发送到数据源的反馈的问题特定逻辑来完成。问题是无法预先知道解析器生成的映射将返回哪些键。并且该过程也可能在很长一段时间内不会结束,因此等待所有结果进入,检查它们并构建包含所需所有列的表不是一种选择。同样重要的是要注意,某些传感器可能仅在极少数情况下被激活,因此即使在相当长的时间之后,新密钥也可能出现在映射中。虽然一般来说,新的键可能随时出现,但在某些情况下,可能知道下一个 x 映射将具有相同的键。在这种情况下,可以像我在这个问题中描述的那样构建临时表并将其连接到主表。我赞成使用一个主表,而不是将数据分散到多个表中,因为对于分析师来说,一张表似乎是最容易使用的。

1 个答案:

答案 0 :(得分:1)

我想不出在 SQLite 中执行此操作的方法。但是在通用 SQL 中,如果您知道公共列,您可以这样做。关键思想是 using 子句将消除重复项。然后,如果您使用 join,您可以获得两个表中的所有列。

这看起来像:

select *
from t1 left join
     (select t2.*
      from t2
      where 1 = 0    -- select no rows!
     ) t2
     using (x)
union all
select *
from (select t1.*
      from t1
      where 1 = 0
     ) t1 right join
     t2
     using (x);

您需要在 using 子句中包含所有常见列,以便它们不会在结果集中重复。 * 会在使用 using 时处理这个问题。

这需要 right join,SQLite 不支持。这是不能用 left join 代替的少数情况之一,因为使用 * 的列排序很重要。

尽管作为思考练习很有趣,但此类代码不应进入生产代码。如果您确实需要执行此类操作,请查找元数据表中的列并构建正确的查询。