FULL OUTER JOIN未按预期工作

时间:2013-12-06 18:06:54

标签: sql sql-server

我正在尝试连接3个表来获取商店/代码列表,但我想要显示所有代码,即使它没有出现在商店下面(作为NULL)。以下是我到目前为止的情况:

Select
    pl.Store_Number
    ,CAST(s.Store_Number as varchar) + ' - ' + s.Store_Name as Store
    ,pc.Plan_Desc
    ,pc.Plan_Cd
    ,pl.Size
    ,pl.Position_Cd
From
    Plan pl
    INNER JOIN Store s ON s.Store_Number = pl.Store_Number
    FULL OUTER JOIN Plan_Code pc ON pc.Plan_Cd = pl.Plan_Cd
Where
    s.End_Date IS NULL
    and pl.Plan_ID <> 0
    and pc.Plan_Cd IN (1,2,3,4,5,6,31,7,8,9,10,11,13,14,36,37
        ,35,17,19,29,23,27,30,15,16,21,32,25,26,42,51,40,44,50,47,41,39)

但结果我只得到每个表中匹配的内容(就像普通的INNER JOIN一样)。我哪里错了?

编辑:

我有一个工作伙伴来帮助我解决这个问题,这就是我们想出的:

Select
    pc.Store_Number
    ,CAST(pc.Store_Number as varchar) + ' - ' + pc.Store_Name as Store
    ,pc.Plan_Desc
    ,pc.Plan_Cd
    ,pl.Size
    ,pl.Position_Cd
From
    (
    Select
        Plan_Desc
        ,Plan_Cd
        ,Store_Number
        ,Store_Name
    From
        Plan_Code pc
        cross join STORE s
    Where
        Plan_Cd IN (1,2,3,4,5,6,31,7,8,9,10,11,13,14,36,37
            ,35,17,19,29,23,27,30,15,16,21,32,25,26,42,51,40,44,50,47,41,39)
        and s.End_Date is null
        and Store_Number <> 0

    ) pc 
    LEFT OUTER JOIN (
        Select  
            pl.Store_Number
            ,CAST(s.Store_Number as varchar) + ' - ' + s.Store_Name as Store
            ,pl.Plan_Cd
            ,pl.Size
            ,pl.Position_Cd
        From
            Plan pl
            INNER JOIN Store s ON s.Store_Number = pl.Store_Number
        Where
            s.End_Date IS NULL
            and pl.Plan_ID <> 0
    ) pl ON pc.Plan_Cd = pl.Plan_Cd and pc.Store_Number = pl.Store_Number
Where
    pc.Store_Number in (Select DISTINCT Store_Number From Plan)
Order By
    Store_Number
    ,pc.Planogram_Cd

2 个答案:

答案 0 :(得分:3)

问题在于,您在WHERE子句中引用了完整联接的每一侧的项目。例如,在这一行:

and pl.Plan_ID <> 0

如果pl.PLan_ID由于完全加入而为空,则表示NULL <> 0不正确,因此不会返回pl.Plan_IDNULL的所有行。

对于pc.Plan_Cd也是如此,如果这是NULL,则以下行不会变为真:

pc.Plan_Cd IN (1,2...

因此,pc.Plan_CdNULL

时,不会返回任何行

我认为你需要在子查询中移动where子句:

SELECT  pl.Store_Number,
        pl.Store
        pc.Plan_Desc,
        pc.Plan_Cd,
        pl.Size,
        pl.Position_Cd
FROM    (   SELECT  pl.Store_Number,
                    CAST(s.Store_Number as varchar) + ' - ' + s.Store_Name AS Store,
                    pl.Size,
                    pl.Position_Cd,
                    pc.Plan_Cd
            FROM    Plan pl
                    INNER JOIN Store s 
                        ON s.Store_Number = pl.Store_Number
            WHERE   s.End_Date IS NULL
            AND     pl.Plan_ID <> 0
        ) pl
        FULL OUTER JOIN 
        (   SELECT  *
            FROM    Plan_Code pc 
            WHERE   pc.Plan_Cd IN (1,2,3,4,5,6,31,7,8,9,10,11,13,14,36,37
                        ,35,17,19,29,23,27,30,15,16,21,32,25,26,42,51,40,44,50,47,41,39)
        ) PC
            ON pc.Plan_Cd = pl.Plan_Cd;

答案 1 :(得分:1)

我会通过两个步骤来解决这个问题,因为即使没有商店,您也想要所有计划编号,您应该将商店表连接到计划表。

select
    pl.store_number
    ,pc.plan_desc
    ,pc.plan_cd
    ,pl.Size
    ,pl.Position_cd
into #plans
from plan pl
    inner join plan_code pc on pc.plan_cd = pl.plan_cd
where pl.plan_id >< 0
    and pc.Plan_Cd IN (1,2,3,4,5,6,31,7,8,9,10,11,13,14,36,37,35,17,19,29,23,27,30,15,16,21,32,25,26,42,51,40,44,50,47,41,39)

select
    p.Store_Number
    ,CAST(s.Store_Number as varchar) + ' - ' + s.Store_Name as Store
    ,p.Plan_Desc
    ,p.Plan_Cd
    ,p.Size
    ,p.Position_Cd
from #plans p
left outer join store s on s.store_number = p.store_number
where s.end_date is null

编辑我之前的答案 - 我假设您希望两个计划表首先加入内部,然后附加商店编号,但不完全清楚。