连接3个表并检索所有表中的所有记录

时间:2009-01-14 04:42:50

标签: sql database join multiple-tables

我正在连接三个表(执行完全外连接),以便我可以从所有表中检索所有记录。我面临的问题是我加入表格的顺序。

表格信息

alt text http://img235.imageshack.us/img235/7980/tableinfoow1.png

(1)如果我连接TABLE1,TABLE2,TABLE3序列中的表,我会得到两行用于记录B组和Level 1。

SELECT DISTINCT 
    (CASE WHEN T0.[TEAM] IS NOT NULL THEN T0.[TEAM] WHEN T1.[TEAM] IS NOT NULL THEN T1.[TEAM] WHEN T2.[TEAM] IS NOT NULL THEN T2.[TEAM] ELSE T0.[TEAM] END) AS [TEAM], 
    (CASE WHEN T0.[LEVEL] IS NOT NULL THEN T0.[LEVEL] WHEN T1.[LEVEL] IS NOT NULL THEN T1.[LEVEL] WHEN T2.[LEVEL] IS NOT NULL THEN T2.[LEVEL] ELSE T0.[LEVEL] END) AS [LEVEL], 
    T0.[VALUE1] AS [VALUE1], 
    T1.[VALUE2] AS [VALUE2], 
    T2.[VALUE3] AS [VALUE3] 

FROM TABLE1 T0
FULL JOIN TABLE2 T1 ON T0.[TEAM] = T1.[TEAM] AND T0.[LEVEL] = T1.[LEVEL] 
FULL JOIN TABLE3 T2 ON T0.[TEAM] = T2.[TEAM] AND T0.[LEVEL] = T2.[LEVEL]

(2)如果我连接TABLE2,TABLE3,TABLE1序列中的表,我在输出中得到正确的行数。

SELECT DISTINCT 
    (CASE WHEN T0.[TEAM] IS NOT NULL THEN T0.[TEAM] WHEN T1.[TEAM] IS NOT NULL THEN T1.[TEAM] WHEN T2.[TEAM] IS NOT NULL THEN T2.[TEAM] ELSE T0.[TEAM] END) AS [TEAM], 
    (CASE WHEN T0.[LEVEL] IS NOT NULL THEN T0.[LEVEL] WHEN T1.[LEVEL] IS NOT NULL THEN T1.[LEVEL] WHEN T2.[LEVEL] IS NOT NULL THEN T2.[LEVEL] ELSE T0.[LEVEL] END) AS [LEVEL], 
    T0.[VALUE1] AS [VALUE1], 
    T1.[VALUE2] AS [VALUE2], 
    T2.[VALUE3] AS [VALUE3] 

FROM TABLE2 T0
FULL JOIN TABLE3 T1 ON T0.[TEAM] = T1.[TEAM] AND T0.[LEVEL] = T1.[LEVEL] 
FULL JOIN TABLE1 T2 ON T0.[TEAM] = T2.[TEAM] AND T0.[LEVEL] = T2.[LEVEL]

我面临的问题是我不知道输入表并将所有这些表作为用户在运行时的输入并执行连接。我不能一次合并两个表,因为我的表在技术上可以一次合并三个以上的表(最多9个或10个)。

如何确保从所有表中获取所有记录(使用完全外部联接),但不要像#1那样获得两行。

4 个答案:

答案 0 :(得分:3)

如果这是您所需要的:

TEAM LEVEL  Value1  Value2  Value3
A   1        1       NULL    NULL
B   1        NULL    1000    900

然后您可以通过以下方式实现这一目标:

SELECT [TEAM], [LEVEL], MAX(v1) Value1, MAX(v2) Value2, MAX(v3) Value3
FROM (
    SELECT [TEAM], [LEVEL], Value1 v1, NULL v2, NULL v3
    FROM TABLE1
    UNION
    SELECT [TEAM], [LEVEL], NULL, Value2, NULL
    FROM TABLE2
    UNION
    SELECT [TEAM], [LEVEL], NULL, NULL, Value3
    FROM TABLE3
) t0
GROUP BY [TEAM], [LEVEL]

您可以根据需要使用任意数量的表格。

答案 1 :(得分:0)

这是一个FULL OUTER JOIN的定义(当使用时,几乎总是表明设计不佳 - 我每年大约使用一次FULL OUTER JOIN。)

也许如果你给出了你想要的结果?

我在想UNION,GROUP BY和COALESCE。

答案 2 :(得分:0)

您需要在第二个连接表达式上添加其他匹配条件,以使其与第二个表的团队/级别值匹配。我还使用ISNULL简化了团队/级别列表达式:

SELECT DISTINCT 
    ISNULL(T0.[TEAM],ISNULL(T1.[TEAM],T2.[TEAM])) AS [TEAM],
    ISNULL(T0.[LEVEL],ISNULL(T1.[LEVEL],T2.[LEVEL])) AS [LEVEL],
    T0.[VALUE1], T1.[VALUE2], T2.[VALUE3]     
FROM TABLE1 T0
FULL JOIN TABLE2 T1 ON T0.[TEAM] = T1.[TEAM] AND T0.[LEVEL] = T1.[LEVEL] 
FULL JOIN TABLE3 T2 ON (T0.[TEAM] = T2.[TEAM] AND T0.[LEVEL] = T2.[LEVEL])
                    OR (T1.[TEAM] = T2.[TEAM] AND T1.[LEVEL] = T2.[LEVEL])

请参阅? T1没有显示在T2的同一行,因为你从未允许这种情况作为匹配的可能性。

答案 3 :(得分:0)

AS u在yru中定义查询distinct,表示在此union中有一个多个条目,因为数据中存在重复,所以最好使用它们。

SELECT [TEAM], [LEVEL], MAX(v1) Value1, MAX(v2) Value2, MAX(v3) Value3
FROM (
    SELECT [TEAM], [LEVEL],  v1, NULL v2, NULL v3
    FROM TABLE1
    UNION ALL
    SELECT [TEAM], [LEVEL], NULL v1, V2, NULL v3
    FROM TABLE2
    UNION ALL
    SELECT [TEAM], [LEVEL], NULL V1, NULL V2, V3
    FROM TABLE3
) t0
GROUP BY [TEAM], [LEVEL]