左连接,where子句

时间:2017-12-04 20:05:44

标签: sql oracle

我想知道为什么这不返回任何值但是如果我在join子句中放置“和r2.ref_nm ='memberPrograStatusType”它会返回值。 'memberPrograStatusType为null。

`select mp.mbr_id
,r1.ref_desc as program_name
,r2.ref_desc as program_status
,mp.nom_dt
,mp.enrl_dt
,mp.end_dt
from icue.mbr_pgm mp
  left join icue.ref r1 on mp.pgm_typ_id = r1.ref_cd
  left join icue.ref r2 on mp.mbr_pgm_sts_typ_id = r2.ref_cd  
where '15-JAN-17' between mp.enrl_dt and nvl(mp.end_dt,sysdate)
    and mp.mbr_id = 46714641
    and r1.ref_nm = 'programType'
    and r2.ref_nm = 'memberPrograStatusType'
'

2 个答案:

答案 0 :(得分:0)

原因是因为当您从where子句中的左连接中的列放置过滤器时,您将其转换为内连接。

但是,如果将过滤器放在join子句上,则过滤器仅适用于左连接表中包含数据的行。

答案 1 :(得分:0)

这里的关键是操作顺序

WHEREJOIN

之后应用

如果将r2.ref_nm = 'x'放入JOIN谓词中,则将其应用于右表,然后将其连接到左表。因为您使用的是LEFT JOIN,这意味着从右表中加入的将在r2.ref_nm = 'x'上进行过滤,但左表中的所有行仍保留在结果中集。

如果您将r2.ref_nm = 'x'放入WHERE子句中,则会在连接发生后将其应用于整个结果集。如果您的过滤器正在查找LEFT JOIN以外的任何内容,这实际上会使您的INNER JOIN成为NULL

TLDR:如果要对LEFT JOIN中的右表进行过滤,则必须在连接谓词中进行过滤,否则将丢失从NULL创建的所有LEFT JOIN值{1}}