2013-04-23 101 views
12

我有多个外连接多FULL OUTER JOIN的多个表

SELECT A.column2 
     , B.column2 
     , C.column2 
FROM 
(
    (SELECT month, column2 FROM table1) A 
    FULL OUTER JOIN 
    (SELECT month, column2 FROM table2) B on A.month= B.month 
    FULL OUTER JOIN 
    (SELECT month, column2 FROM table3) C on A.month= C.month 
) 

现在最后加入是有一个问题,它的重复,当A的月比B多,但如果B有更多的一个月是一个我们现在有重复的月的A有C的外部连接,所以我想有两个表内的全外部连接可能会解决问题?任何深入的联系?

样本数据(错误)

╔════════════╦═════════╦═════════════╗ 
║ Revenue ║ Budget ║ ActualMonth ║ 
╠════════════╬═════════╬═════════════╣ 
║  6.9172 ║ 3.5046 ║ Jan   ║ 
║  7.3273 ║ 3.7383 ║ Feb   ║ 
║  7.3273 ║ 3.9719 ║ Mar   ║ 
║  7.2726 ║ 4.2056 ║ Apr   ║ 
║  7.2595 ║ 6.7757 ║ May   ║ 
║  7.2726 ║ 6.7757 ║ Jun   ║ 
║  0.41 ║ 0.00 ║ Jul   ║ 
║  0.41 ║ 0.00 ║ Aug   ║ 
║  0.41 ║ 0.00 ║ Sep   ║ 
║  0.41 ║ 0.00 ║ Oct   ║ 
║  7.4696 ║ 0.00 ║ Nov   ║ 
║  7.4696 ║ 0.00 ║ Dec   ║ 
║  0.00 ║ 9.3457 ║ Sep   ║ 
║  0.00 ║ 16.3551 ║ Dec   ║ 
║  0.00 ║ 6.3084 ║ Jul   ║ 
║  0.00 ║ 14.0186 ║ Oct   ║ 
║  0.00 ║ 16.3551 ║ Nov   ║ 
║  0.00 ║ 6.1915 ║ Aug   ║ 
╚════════════╩═════════╩═════════════╝ 

正确性

╔════════════╦═════════╦═════════════╗ 
║ Revenue ║ Budget ║ ActualMonth ║ 
╠════════════╬═════════╬═════════════╣ 
║  6.9172 ║ 3.5046 ║ Jan   ║ 
║  7.3273 ║ 3.7383 ║ Feb   ║ 
║  7.3273 ║ 3.9719 ║ Mar   ║ 
║  7.2726 ║ 4.2056 ║ Apr   ║ 
║  7.2595 ║ 6.7757 ║ May   ║ 
║  7.2726 ║ 6.7757 ║ Jun   ║ 
║  0.41 ║ 6.3084 ║ Jul   ║ 
║  0.41 ║ 6.1915 ║ Aug   ║ 
║  0.41 ║ 9.3457 ║ Sep   ║ 
║  0.41 ║ 14.0186 ║ Oct   ║ 
║  7.4696 ║ 16.3551 ║ Nov   ║ 
║  7.4696 ║ 16.3551 ║ Dec   ║ 
╚════════════╩═════════╩═════════════╝ 
+3

请添加样本数据和预期输出。 – TechDo 2013-04-23 11:20:45

+3

外连接是可交换的。 '外连接B外连接C'与'外连接C外连接B'相同。事实上,它甚至与'A外部连接(B外部连接C)相同'我不明白你的问题*(注意:这适用于B和C连接到A)* – RichardTheKiwi 2013-04-23 11:21:14

+0

请检查示例数据 – brykneval 2013-04-23 11:52:42

回答

17
SELECT A.column2 
     , B.column2 
     , C.column2 
FROM 
(
    (SELECT month, column2 FROM table1) A 
    FULL OUTER JOIN 
    (SELECT month, column2 FROM table2) B on A.month= B.month 
    FULL OUTER JOIN 
    (SELECT month, column2 FROM table3) C on ISNULL(A.month, B.month) = C.month 
) 
+0

这应该解决您的问题与C.如果需要,随意使用与B相同的逻辑(ISNULL)。 – Serge 2013-04-25 14:22:32

+0

感谢您的帮助:-) – brykneval 2013-04-25 16:08:58

+1

取决于环境,ISNULL()等同于coalesce还是oracle的NVL()?加入NVL(A.ID,B.ID)= C.ID以相同的方式运行 – 2014-04-01 18:31:01

3

我能想到的2种蝙蝠,你可以解决这个问题,这取决于实际的逻辑是定义你想要的结果。

第一种也是最傻瓜的方法是使用GROUP BY月份,并使用像MAX(column2)这样的聚合函数来获取非零行,或者如果有多个非零行要添加,请使用SUM()。如果有一个聚合函数满足您的逻辑意图,这是最好的解决方案。

另一种方法是在JOIN中包含更多条件,例如“WHERE a.month = b.month AND b.column2> 0”,但如果可能存在多个不相关的问题,则仍不能解决问题。零行。

+0

我同意Tab,使用GROUP BY和SUM()或MAX() – 2013-04-23 13:35:19

1

select month, sum(a) a, sum(b) b, sum(c) c from (
    SELECT month, column2 A, 0 B, 0 C FROM table1 
    union 
    SELECT month, 0 A, column2 B, 0 C FROM table2 
    union 
    SELECT month, 0 A, 0 B, column2 C FROM table3 
) x 
group by month 
1

使用带有COALESCE功能选项来确定列分组。

SELECT COALESCE(t1.Month, t2.Month, t3.Month) AS Month, 
     SUM(ISNULL(t1.Col1, 0)) AS t1Col1, 
     SUM(ISNULL(t2.Col1, 0)) AS t2Col1, 
     SUM(ISNULL(t3.Col1, 0)) AS t3Col1 
FROM dbo.table1 t1 FULL OUTER JOIN dbo.table2 t2 ON t1.Month = t2.Month 
        FULL OUTER JOIN dbo.table3 t3 ON t1.Month = t3.Month 
GROUP BY COALESCE(t1.Month, t2.Month, t3.Month) 
2

一要做到这一点可以从所有三个表中创建所有可能的数据“锚”表,然后使用left outer join方式:

select 
    A.column2, 
    B.column2, 
    C.column2 
from (
    select distinct month from table1 
    union 
    select distinct month from table2 
    union 
    select distinct month from table3 
) as X 
    left outer join table1 as A on A.month = X.month 
    left outer join table2 as B on B.month = X.month 
    left outer join table3 as C on C.month = X.month