FULL OUTER JOIN的值出现在2个不同的字段中

时间:2016-03-24 15:22:40

标签: sql sql-server tsql

这是我的查询:

SELECT
COALESCE ([dbo].[RSA_BIRMINGHAM_1941$].TOS,
[dbo].[RSA_CARDIFFREGUS_2911$].TOS,[dbo].[RSA_CASTLEMEAD_1941$].TOS,
[dbo].[RSA_CHELMSFORD_1941$].TOS) AS [TOS Value]

,RSA_BIRMINGHAM_1941$.Percentage            AS [Birmingham]
,RSA_CARDIFFREGUS_2911$.Percentage          AS [Cardiff Regus]
,[dbo].[RSA_CASTLEMEAD_1941$].Percentage    AS [Castlemead]
,[dbo].[RSA_CHELMSFORD_1941$].Percentage    AS [Chelmsford]

FROM [dbo].[RSA_BIRMINGHAM_1941$] 
FULL OUTER JOIN [dbo].[RSA_CARDIFFREGUS_2911$] 
ON [dbo].[RSA_BIRMINGHAM_1941$].TOS = [dbo].[RSA_CARDIFFREGUS_2911$].TOS

FULL OUTER JOIN [dbo].[RSA_CASTLEMEAD_1941$] 
ON [dbo].[RSA_BIRMINGHAM_1941$].TOS = [dbo].[RSA_CASTLEMEAD_1941$].TOS

FULL OUTER JOIN [dbo].[RSA_CHELMSFORD_1941$] 
ON [dbo].[RSA_BIRMINGHAM_1941$].TOS = [dbo].[RSA_CHELMSFORD_1941$].TOS

这是输出:

TOS Value        Birmingham   Cardiff Regus   Castlemead    Chelmsford
default (DSCP 0)   61.37%       61.74%         99.48%         79.78%
af11 (DSCP 10)     15.22%       4.63%          0.00%          6.16%
af33 (DSCP 30)     11.49%       15.44%         NULL           7.33%
af31 (DSCP 26)     8.86%        13.85%         0.01%          5.59%
ef (DSCP 46)       1.91%        3.72%          0.49%          0.91%
af41 (DSCP 34)     0.70%        0.03%          0.01%          0.05%
cs4 (DSCP 32)      0.15%        0.20%          NULL           0.10%
af12 (DSCP 12)     0.12%        NULL           NULL           NULL
cs3 (DSCP 24)      0.06%        0.11%          0.01%          0.04%
af21 (DSCP 18)     0.05%        0.05%          0.00%          0.02%
cs6 (DSCP 48)      NULL         0.23%          NULL           NULL
cs6 (DSCP 48)      NULL         NULL           0.00%          NULL
af32 (DSCP 28)     NULL         NULL           NULL           0.02%

如果您查看TOS列并查看值cs6(DSCP 48),您将看到它已被复制。 应该只有1个cs6(DSCP 48)行但由于某种原因,cs6(DSCP 48)的Castlemead值(0.00%)已被创建为单独的列。

如果有意义,每个TOS值应该只有一行,所以请告诉我哪里出错?

3 个答案:

答案 0 :(得分:1)

您获得的结果与预期一致。这是因为连接都是相对于第一个表。如果第二个表中的TOS与将生成新记录的第一个表不匹配。如果第三个表中的TOS与第一个表不匹配,将再次生成新记录。没有线索让引擎知道应该组合这样的实例 一个结果。

可能有几种方法可以解决这个问题。我将建议您引入一个UNION子选择,它将组合所有TOS值,然后INNER JOIN到四个表中的每一个。

SELECT       REF.TOS AS [TOS Value]
            ,RSA_BIRMINGHAM_1941$.Percentage    AS [Birmingham]
            ,RSA_CARDIFFREGUS_2911$.Percentage  AS [Cardiff Regus]
            ,RSA_CASTLEMEAD_1941$.Percentage    AS [Castlemead]
            ,RSA_CHELMSFORD_1941$.Percentage    AS [Chelmsford]

FROM       ( SELECT TOS FROM RSA_BIRMINGHAM_1941$   UNION
             SELECT TOS FROM RSA_CARDIFFREGUS_2911$ UNION
             SELECT TOS FROM RSA_CASTLEMEAD_1941$   UNION
             SELECT TOS FROM RSA_CHELMSFORD_1941$
           ) AS REF
INNER JOIN RSA_BIRMINGHAM_1941$   ON REF.TOS = RSA_BIRMINGHAM_1941$.TOS
INNER JOIN RSA_CARDIFFREGUS_2911$ ON REF.TOS = RSA_CARDIFFREGUS_2911$.TOS
INNER JOIN RSA_CASTLEMEAD_1941$   ON REF.TOS = RSA_CASTLEMEAD_1941$.TOS
INNER JOIN RSA_CHELMSFORD_1941$   ON REF.TOS = RSA_CHELMSFORD_1941$.TOS

答案 1 :(得分:0)

查询使用表别名更容易编写和读取。问题是第二个FULL OUTER JOIN中的匹配。 FROM子句需要如下所示:

FROM [dbo].[RSA_BIRMINGHAM_1941$] b FULL OUTER JOIN
     [dbo].[RSA_CARDIFFREGUS_2911$] cr
     ON b.TOS = cr.TOS FULL OUTER JOIN
     [dbo].[RSA_CASTLEMEAD_1941$] cm
     ON cm.TOS IN (b.TOS, cr.TOS) FULL OUTER JOIN
     [dbo].[RSA_CHELMSFORD_1941$] cf
     ON cf.TOS IN (b.TOS, cr.TOS, cm.TOS)

换句话说,通过与后面的联接中只有一个TOS字段进行比较,您可能会加入一个不匹配的列 - 从而获得重复。一个FULL OUTER JOIN没问题。多个FULL OUTER JOIN很棘手。我经常使用UNION ALL个查询。

答案 2 :(得分:0)

感谢@trincot,因为他是为我所寻找的结果奠定了基金会的人。这是解决了我的问题的查询:

SELECT       REF.TOS AS [TOS Value]
        ,RSA_BIRMINGHAM_1941$.Percentage    AS [Birmingham]
        ,RSA_CARDIFFREGUS_2911$.Percentage  AS [Cardiff Regus]
        ,RSA_CASTLEMEAD_1941$.Percentage    AS [Castlemead]
        ,RSA_CHELMSFORD_1941$.Percentage    AS [Chelmsford]

 FROM    
         (SELECT TOS FROM RSA_BIRMINGHAM_1941$   UNION
         SELECT TOS FROM RSA_CARDIFFREGUS_2911$ UNION
         SELECT TOS FROM RSA_CASTLEMEAD_1941$   UNION
         SELECT TOS FROM RSA_CHELMSFORD_1941$) AS REF

       FULL OUTER JOIN RSA_BIRMINGHAM_1941$   ON REF.TOS =  
       RSA_BIRMINGHAM_1941$.TOS
       FULL OUTER JOIN RSA_CARDIFFREGUS_2911$ ON REF.TOS =
       RSA_CARDIFFREGUS_2911$.TOS
       FULL OUTER JOIN RSA_CASTLEMEAD_1941$   ON REF.TOS = 
       RSA_CASTLEMEAD_1941$.TOS
       FULL OUTER JOIN RSA_CHELMSFORD_1941$   ON REF.TOS = 
       RSA_CHELMSFORD_1941$.TOS

       ORDER BY [TOS Value]

,结果如下所示:

TOS Value      Birmingham   CardiffRegus    Castlemead  Chelmsford
af11 (DSCP 10)  15.22%      4.63%           0.00%        6.16%
af12 (DSCP 12)  0.12%       NULL            NULL         NULL
af21 (DSCP 18)  0.05%       0.05%           0.00%        0.02%
af31 (DSCP 26)  8.86%       13.85%          0.01%        5.59%
af32 (DSCP 28)  NULL        NULL            NULL         0.02%
af33 (DSCP 30)  11.49%      15.44%          NULL         7.33%
af41 (DSCP 34)  0.70%       0.03%           0.01%        0.05%
cs3 (DSCP 24)   0.06%       0.11%           0.01%        0.04%
cs4 (DSCP 32)   0.15%       0.20%           NULL         0.10%
cs6 (DSCP 48)   NULL        0.23%           0.00%        NULL
defau(DSCP 0)   61.37%      61.74%          99.48%       79.78%
ef (DSCP 46)    1.91%       3.72%           0.49%        0.91%