Union Many Tables Together,正确的连接类型?

时间:2014-01-06 17:32:10

标签: sql postgresql

我想要加入10个以上的桌子。这是我需要对3个表做什么的基本示例。

输入表

Table 1
    ID, Time, Field1
    1, Mon, 5
    1, Tue, 6
    1, Wed, 7 

Table 2
    ID, Time, Field1
    1, Tue, 99
    1, Wed, 199
    1, Thu, 299

Table 3
    ID, Time, Field1
    1, Wed, 777
    1, Thu, 888
    1, Fri, 999

期望的输出表

Table Output
    ID, Time, T1.Field1, T2.Field1, T3.Field1
    1, Mon, 5, NULL, NULL
    1, Tue, 6, 99, NULL
    1, Wed, 7, 199, 777
    1, Thu, NULL, 299, 888
    1, Fri, NULL, NULL, 999

我尝试了以下(有9个表),但它没有返回。这是由于运行时间还是我做了错误的加入?

Select 
    id, time, t1.field1, t2.field1, t3.field3
From
    table1 t1
FULL JOIN table2 t2 using (id, time)
FULL JOIN table3 t3 using (id, time);

3 个答案:

答案 0 :(得分:0)

您需要左外连接。这将获取t1中的所有行以及t2,t3等中的任何匹配数据,但如果没有匹配数据则返回NULLS。

答案 1 :(得分:0)

您的查询实际上看起来是正确的,或者至少是理智的,禁止使用不明确的列名称和间隙,以防止在表3中存在行但在table1和table2中存在行时显示行。所以从第三个表开始,你需要在整个地方合并:

Select 
    coalesce(t1.id, t2.id, t3.id, ...) as id,
    coalesce(t1.time, t2.time, t3.time, ...) as time,
    t1.field1 as field1,
    t2.field1 as field2, ...
From
    table1 t1
FULL JOIN table2 t2 using (id, time)
FULL JOIN table3 t3 on t3.id = coalesce(t1.id, t2.id)
                   and t3.time = coalesce(t1.time, t2.time)
FULL JOIN ...

如果你想填补这些漏洞,请查看generate_series() - 如果你最终使用后者,left join并且没有合并将没有问题。

此外,认真重新审视该架构,并避免加入上述混乱任何 - 如果你这样做,seq扫描全部都会得到保证。

答案 2 :(得分:0)

伪表作为主表是唯一的id / time组合的完整列表,并且LEFT JOINing off以确保所有其他表都可以表示?

SELECT m.id,m.time,t1.field,t2.field,t3.field
FROM (SELECT DISTINCT id,time FROM (
    SELECT id,time FROM t1 
    UNION 
    SELECT id,time FROM t2
    UNION
    SELECT id,time FROM t3)m) m
LEFT JOIN t1 ON t1.id=m.id AND t1.time=m.time
LEFT JOIN t2 ON t2.id=m.id AND t2.time=m.time
LEFT JOIN t3 ON t3.id=m.id AND t3.time=m.time

效率可能不是最好的。