LEFT OUTER JOIN连接3个表

3

我将更新使用旧的外部连接构造(=* 和 *=)的查询。我有3个表需要包含在外部连接中。

原始查询如下:

SELECT  s.SkillID ,
        NULL AS Signature ,
        NULL AS DPL ,
        CASE WHEN ISNULL(ds.DPL, dg.DPL) IS NULL
             THEN p.ScaleTo - p.ScaleFrom + 1
             ELSE ISNULL(ds.DPL, dg.DPL)
        END AS DefaultDPL
FROM    tbJobs j ,
        tbSkills s 
        INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,
        tbPerfScales p ,
        tbDPLs ds ,
        tbDPLs dg
WHERE   j.JobID = 866
        AND ( ds.LevelID=*j.LevelID
              AND ds.IDType = 1
              AND ds.GroupOrSkillID=*s.SkillID
            )
        AND ( dg.LevelID=*j.LevelID
              AND dg.IDType = 0
              AND dg.GroupOrSkillID=*sg.SkillGroupID
            )
        AND ( ( s.PerfScaleID IS NOT NULL
                AND p.PerfScaleID = s.PerfScaleID
              )
              OR ( s.PerfScaleID IS NULL
                   AND p.PerfScaleID = sg.PerfScaleID
                 )
            )

我正在进行:

SELECT  s.SkillID ,
        NULL AS Signature ,
        NULL AS DPL ,
        CASE WHEN ISNULL(ds.DPL, dg.DPL) IS NULL
             THEN p.ScaleTo - p.ScaleFrom + 1
             ELSE ISNULL(ds.DPL, dg.DPL)
        END AS DefaultDPL
FROM    tbPerfScales p ,
        tbSkills s
        INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,
        tbJobs j
        LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
                                     AND s.SkillID = ds.GroupOrSkillID
        LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
                                     AND sg.SkillGroupID = dg.GroupOrSkillID
WHERE   j.JobID = 866
        AND ds.IDType = 1
        AND dg.IDType = 0
        AND ( ( s.PerfScaleID IS NOT NULL
                AND p.PerfScaleID = s.PerfScaleID
              )
              OR ( s.PerfScaleID IS NULL
                   AND p.PerfScaleID = sg.PerfScaleID
                 )
            )

因为某些原因,我遇到了以下错误:

无法绑定多部分标识符“s.SkillID”。

我知道错误出现在这个部分:

    tbJobs j
    LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
                                 AND s.SkillID = ds.GroupOrSkillID

我不确定我做错了什么。

谢谢任何帮助。 Jose


当你这样做时,你可能会发现与过去不同的结果,因为隐式语法中的外连接在许多情况下甚至从SQL Server 2000开始就产生了错误的结果。因此,你要修复的每个查询都有可能一开始就是不正确的。如果混合使用隐式和显式语法,你可能会得到错误的结果,必须将所有连接转换为正确的结果。 - HLGEM
这可能对某些情况成立,这就是为什么我正在对它们进行大量测试以确保它们产生准确的结果。感谢您的建议。 - JRGuay
2个回答

6

这句话后面有一个逗号。

INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,

这是因为您在它后面使用了tbJobs, 而它应该在其他表中。我建议使用CROSS JOIN代替仅在FROM子句中有多个表,这样更清晰。以下是重写查询的基础内容,应该可以工作,尽管您应该能够轻松摆脱大部分交叉连接。
SELECT  s.SkillID ,
        NULL AS Signature ,
        NULL AS DPL ,
        CASE WHEN ISNULL(ds.DPL, dg.DPL) IS NULL
             THEN p.ScaleTo - p.ScaleFrom + 1
             ELSE ISNULL(ds.DPL, dg.DPL)
        END AS DefaultDPL
FROM    tbPerfScales p 
        CROSS JOIN tbSkills s
        CROSS JOIN tbJobs j
        INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID
        LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
                                     AND s.SkillID = ds.GroupOrSkillID
        LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
                                     AND sg.SkillGroupID = dg.GroupOrSkillID
WHERE   j.JobID = 866
        AND ds.IDType = 1
        AND dg.IDType = 0
        AND ( ( s.PerfScaleID IS NOT NULL
                AND p.PerfScaleID = s.PerfScaleID
              )
              OR ( s.PerfScaleID IS NULL
                   AND p.PerfScaleID = sg.PerfScaleID
                 )
            )

谢谢Darren。我加了逗号是因为我正在重写原始查询,基本上我想要(需要)的就是消除旧的外部连接格式。那里的逗号是为了分隔其他连接的一部分,你认为这可能是问题吗?我没有任何列/方法将前面的3个表连接到后面的2个表。 :( - JRGuay
是的,在连接操作中不应该有逗号,所以将tbJobs移动到上面。我已经更新了我的问题,加入了交叉连接的用法。 - Darren Kopp

3

不能混用不同的SQL语法。如果您采用ANSI-92标准,则需要更正所有联接,而不仅仅是外部联接。保持一致性很重要。

逗号现在是不正确的语法。您需要为每个表添加一个联接,或按照Darren的答案将它们拆分成交叉应用程序。

FROM    tbPerfScales p ,
        tbSkills s
        INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID ,
        tbJobs j
        LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
                                     AND s.SkillID = ds.GroupOrSkillID
        LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
                                     AND sg.SkillGroupID = dg.GroupOrSkillID

需要翻译的内容大致如下:

它需要符合以下要求:

  FROM    tbPerfScales p 
     INNER JOIN tbSkills s ON  p.<field> = s.<field>
        INNER JOIN tbSkillGroups sg ON s.SkillGroupID = sg.SkillGroupID
        INNER JOIN tbJobs j on j.<field> = <table p? sg? not sure>.<field>
        LEFT OUTER JOIN tbDPLs ds ON j.LevelID = ds.LevelID
                                     AND s.SkillID = ds.GroupOrSkillID
        LEFT OUTER JOIN tbDPLs dg ON j.LevelID = dg.LevelID
                                     AND sg.SkillGroupID = dg.GroupOrSkillID

它实际上有很多道理,只是我没有要连接其他表的列。看到原始查询了吗?不确定如何将其提取出来。 - JRGuay

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接