我正在努力实现这样的目标:
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行值。
谢谢!
答案 0 :(得分:1)
如果你有任何WHERE条件应用于LEFT JOINed表(在这种情况下是PR),那么连接将被有效地转换为INNER JOIN - 因为WHERE条件明显排除了所有不存在的PR行。
答案 1 :(得分:0)
如果您希望返回PR
的所有行以及来自RS
的匹配行,那么您的外部联接会向后切换。
如果你说:
rs LEFT JOIN pr
返回rs
的所有行,以及来自pr
的匹配行。 rs
中pr
中没有匹配行的任何行也将返回,缺少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
子句。