使用FULL OUTER JOIN / COALESCE时重复结果

时间:2012-11-14 14:18:16

标签: sql sql-server sql-server-2008-r2

问题在于:

CREATE TABLE #datesX
    (
    [Name] [varchar] (8) NULL
    , [MarriedDate] datetime NULL
    , [HappyScoreX] [int] NULL
    ) 
INSERT INTO #datesX 
    values 
     ('TIM', null, 20),
     ('RAJ', '01 jan 2012', 20),
     ('PAUL', '01 jan 1960', 20)


CREATE TABLE #datesY
    (
    [Name] [varchar] (8) NULL
    , [FirstSprogDate] datetime NULL
    , [HappyScoreY] [int] NULL
    ) 
INSERT INTO #datesY 
    values 
     ('TIM', '01 jan 1995', 20),
     ('RAJ', '20 JUN 2013', 20),
     ('JASE', null, 20),
     ('PAUL', '01 jan 1970', 20)


CREATE TABLE #datesZ
    (
    [Name] [varchar] (8) NULL
    , [FoundGodDate] datetime NULL
    , [HappyScoreZ] [int] NULL
    ) 
INSERT INTO #datesZ 
    values 
     ('TIM', null, 20),
     ('RAJ', null, 20),
     ('JASE', '01 DEC 2012', 20),
     ('PAUL', '01 jan 1970', 20)




SELECT 
        [Name] = COALESCE(x.Name, y.Name, z.Name), 
        x.[MarriedDate],
        y.[FirstSprogDate],
        z.[FoundGodDate],
        [HappyScoreX] = SUM(ISNULL(x.[HappyScoreX],0.0)),
        [HappyScoreY] = SUM(ISNULL(y.[HappyScoreY],0.0)),
        [HappyScoreZ] = SUM(ISNULL(z.[HappyScoreZ],0.0))
FROM 
        #datesX x
        FULL OUTER JOIN #datesY y ON
                x.Name = y.Name 
        FULL OUTER JOIN #datesZ z ON
                x.Name = z.Name 
GROUP BY
        COALESCE(x.Name, y.Name, z.Name), 
        x.[MarriedDate],
        y.[FirstSprogDate],
        z.[FoundGodDate]

我可以理解为什么JASE的记录被重复 - 我如何修改查询以便JASE只有一条记录?

4 个答案:

答案 0 :(得分:3)

请尝试此连接:

FULL OUTER JOIN #datesY y ON
       x.Name = y.Name 
FULL OUTER JOIN #datesZ z ON
       coalesce(x.Name, y.name) = z.Name 

答案 1 :(得分:1)

每个名称需要一行。我的建议是首先建立密钥,然后去获取行。

CREATE TABLE #nameKeys
(
  [Name] varchar(8) NOT NULL PRIMARY KEY
)

INSERT INTO #nameKeys ([Name])
SELECT DISTINCT [Name] FROM #datesX WHERE [Name] is not null
UNION
SELECT DISTINCT [Name] FROM #datesYY WHERE [Name] is not null
UNION
SELECT DISTINCT [Name] FROM #datesZ WHERE [Name] is not null


--Then later...

FROM
  #nameKeys n
  LEFT JOIN #datesX x ON n.[Name] = x.[Name]
  LEFT JOIN #datesY y ON n.[Name] = y.[Name]
  LEFT JOIN #datesZ z ON n.[Name] = z.[Name]

答案 2 :(得分:1)

您遇到的麻烦是#datesX上有两个FULL OUTER JOINS。由于JASE的#datesX中没有行,因此您可以从Y和Z表中返回行,但是您的上一个Full外部会确定您应该将X.Name与Z.Name匹配。以下代码将为您提供您想要的(我认为|)

SELECT 
        [Name] = COALESCE(x.Name, y.Name, z.Name), 
        x.[MarriedDate],
        y.[FirstSprogDate],
        z.[FoundGodDate],
        [HappyScoreX] = SUM(ISNULL(x.[HappyScoreX],0.0)),
        [HappyScoreY] = SUM(ISNULL(y.[HappyScoreY],0.0)),
        [HappyScoreZ] = SUM(ISNULL(z.[HappyScoreZ],0.0))
FROM 
        #datesX x
        FULL OUTER JOIN #datesY y ON
                x.Name = y.Name 
        FULL OUTER JOIN #datesZ z ON
                z.Name = COALESCE(x.Name, y.Name)
GROUP BY
        COALESCE(x.Name, y.Name, z.Name), 
        x.[MarriedDate],
        y.[FirstSprogDate],
        z.[FoundGodDate]

答案 3 :(得分:1)

为了进一步理解David B的答案,使用Common Table Expression

是有意义的
;WITH NameKeys
AS
(
    SELECT DISTINCT [Name] FROM #datesX WHERE [Name] is not null
    UNION
    SELECT DISTINCT [Name] FROM #datesYY WHERE [Name] is not null
    UNION
    SELECT DISTINCT [Name] FROM #datesZ WHERE [Name] is not null
)
SELECT 
        n.[Name], 
        x.[MarriedDate],
        y.[FirstSprogDate],
        z.[FoundGodDate],
        [HappyScoreX] = SUM(ISNULL(x.[HappyScoreX],0.0)),
        [HappyScoreY] = SUM(ISNULL(y.[HappyScoreY],0.0)),
        [HappyScoreZ] = SUM(ISNULL(z.[HappyScoreZ],0.0))
FROM NameKeys n
LEFT JOIN #datesX x ON n.[Name] = x.[Name]
LEFT JOIN #datesY y ON n.[Name] = y.[Name]
LEFT JOIN #datesZ z ON n.[Name] = z.[Name]