SQL Left Join不返回表中的所有值

时间:2015-01-07 22:07:41

标签: mysql sql-server

我正在努力实现这样的目标:

Report_Code 325 10 Report_line_text $ 100

Report_Code 326 20 Report_line_text NULL

Report_Code 327 30 Report_line_text $ 300

相反,我得到了这个:

Report_Code 325 10 Report_line_text $ 100

Report_Code 327 30 Report_line_text $ 300

使用此代码:

SELECT   PR.RPT_CD 
    ,PR.BR_ID
    ,PR.RPT_LN_SEQ_NUM
    ,PR.RPT_LN_TXT
    ,RS.RSLT_AMT
FROM table 1 RS
  LEFT JOIN table 2 PR
  ON PR.BR_ID = RS.BR_ID
  AND RS.RPT_CD = PR.RPT_CD
WHERE RS.RPT_CD = @REPORT
  AND YR_NUM = @CONTRACT_YR
  AND QTR_NUM = @QTR
  AND PG_CD = @PG_CD
  AND CTRL_CD IN ('ABC', 'DEF', 'GHI')
ORDER BY PR.RPT_LN_SEQ_NUM  

为什么左边的第2行连接掉线?我需要看到第2行的NULL行值。

谢谢!

2 个答案:

答案 0 :(得分:1)

如果你有任何WHERE条件应用于LEFT JOINed表(在这种情况下是PR),那么连接将被有效地转换为INNER JOIN - 因为WHERE条件明显排除了所有不存在的PR行。

答案 1 :(得分:0)

如果您希望返回PR的所有行以及来自RS的匹配行,那么您的外部联接会向后切换。

如果你说:

rs LEFT JOIN pr

返回rs的所有行,以及来自pr的匹配行。 rspr中没有匹配行的任何行也将返回,缺少pr行的虚拟行NULL值。

要从pr返回所有行,您需要交换它,并将pr放在联接的“左侧”

pr LEFT JOIN rs

然后,即使在pr中找不到匹配的行,也会返回rs中的所有行。


其他几点说明:

请使用表名或最好是短别名限定所有列引用。查询中的某些列引用是合格的,但WHERE子句中的某些列引用不是;所以我们这些可怜的读者无法从声明中说出CTRL_CD是指RS还是PR中的一列。 (如果这是在一个过程的上下文中,我们甚至不能知道那些是对列的引用,而不是过程变量。养成了对所有列引用进行限定的习惯,为了理解你的SQL背后的灵魂的理智,让你的SQL更容易阅读意味着它将花费更少来维护代码。

如果问题不是向后交换连接,那么最可能的问题是WHERE子句中的谓词等于在{PR列上指定IS NOT NULL条件。 1}}表,这将有效地否定连接的“外部性”。在这种情况下,只需将该谓词从WHERE子句重定位到ON子句。