2017-05-31 155 views
0

我有一个查询返回〜97K记录,因为我使用的是一个内部联接。现在我想用左连接来显示右表上的空记录(应该是大约300k条记录)。这是实际的查询(INNER JOIN):转换INNER JOIN到左JOIN - SQL

select artnr as "Article number", ardbez1 as "Article description ", arpadrnr as "Supplier code", cd.ADPPHYSLAND as "Country of this supplier code", p.adrnr as "Parent supplier code", p.adrkname as "Name of parent", pd.ADPPHYSLAND as "Country of parent ", arppreis as "Price", arpwae as "Unit", arzwert as "COO", atatarnr as "HS Code" 
    from mic_ccs_artikel, mic_ccs_artikeldetail, mic_ccs_artikelpreis, mic_dna_adressen c, mic_dna_adrdetail cd, mic_dna_adressen p, mic_dna_adrrelation, mic_dna_adrdetail pd, mic_ccs_artikelzoll, mic_ccs_artikeltarif 
    where artsid = ardartsid 
    and arddatstart <= sysdate 
    and nvl(arddatend, '01.01.4000') >= sysdate 
    and artsid = arpartsid 
    and ARPPREISART = 'VP' 
    and arpdatstart <= sysdate 
    and nvl(arpdatend, '01.01.4000') >= sysdate 
    and c.adrsid = cd.adpadrsid 
    and arpadrnr = c.adrnr 
    and cd.adpdatvon <= sysdate 
    and nvl(cd.adpdatbis, '01.01.4000') >= sysdate 
    and c.adrmandant = 'S1' 
    and c.adrwerk = 'V1' 
    and p.adrmandant = 'S1' 
    and p.adrwerk = 'V1' 
    and p.adrsid = arlrelsid1 
    and c.adrsid = arlrelsid2 
    and p.adrsid = pd.adpadrsid 
    and pd.adpdatvon <= sysdate 
    and nvl(pd.adpdatbis, '01.01.4000') >= sysdate 
    and artsid = arzartsid 
    and arztyp = 'URLD' 
    and arzadrnr = c.adrnr 
    and arzdatstart <= sysdate 
    and nvl(arzdatend, '01.01.4000') >= sysdate 
    and artsid = ataartsid 
    and ATAREGION = 'SE' 
    and atatarart='EXPORT' 
    and atadatstart <= sysdate 
    and nvl(atadatend, '01.01.4000') >= sysdate 
    ; 

然后我试图 “转换” 它LEFT JOIN,但它总是显示了同样的结果:

select artnr as "Article number", ardbez1 as "Article description ", arpadrnr as "Supplier code", cd.ADPPHYSLAND as "Country of this supplier code", p.adrnr as "Parent supplier code", p.adrkname as "Name of parent", pd.ADPPHYSLAND as "Country of parent ", arppreis as "Price", arpwae as "Unit", arzwert as "COO", atatarnr as "HS Code" 
from mic_ccs_artikel, mic_ccs_artikeldetail, mic_ccs_artikelpreis, mic_dna_adressen c, mic_dna_adrdetail cd, mic_dna_adressen p, mic_dna_adrrelation, mic_dna_adrdetail pd, mic_ccs_artikelzoll, mic_ccs_artikeltarif 
where artsid = ardartsid(+) 
and arddatstart <= sysdate 
and nvl(arddatend, '01.01.4000') >= sysdate 
and artsid = arpartsid(+) 
and ARPPREISART = 'VP' 
and arpdatstart <= sysdate 
and nvl(arpdatend, '01.01.4000') >= sysdate 
and c.adrsid = cd.adpadrsid(+) 
and arpadrnr = c.adrnr 
and cd.adpdatvon <= sysdate 
and nvl(cd.adpdatbis, '01.01.4000') >= sysdate 
and c.adrmandant = 'S1' 
and c.adrwerk = 'V1' 
and p.adrmandant = 'S1' 
and p.adrwerk = 'V1' 
and p.adrsid = arlrelsid1(+) 
and c.adrsid = arlrelsid2 
and p.adrsid = pd.adpadrsid 
and pd.adpdatvon <= sysdate 
and nvl(pd.adpdatbis, '01.01.4000') >= sysdate 
and artsid = arzartsid(+) 
and arztyp = 'URLD' 
and arzadrnr = c.adrnr 
and arzdatstart <= sysdate 
and nvl(arzdatend, '01.01.4000') >= sysdate 
and artsid = ataartsid(+) 
and ATAREGION = 'SE' 
and atatarart='EXPORT' 
and atadatstart <= sysdate 
and nvl(atadatend, '01.01.4000') >= sysdate 
; 

为什么它总是显示相同的结果?

+0

使用别名,我们无法理解哪些列属于哪个表 –

+2

我建议您使用左外连接语法 –

+2

您应该限定每个属性,使用别名并开始使用ANSI连接语法(join ... on ... )。你的直接问题可能是你的左连接表在你的'where'中也有条件,有效地将它变成内连接。 – HoneyBadger

回答

1

使用左连接和where子句回应评论中的情绪可能会导致一些意外行为。有关更多详情,请参阅我的回答here。基本上,你应该切换到使用ANSI语法和别名表。在你的情况下,这看起来像

select * -- select whichever fields you want here 
    from mic_ccs_artikel a -- only one table in the from clause 
    left join mic_ccs_artikeldetail b on b.someID = a.someID -- join conditions here 
    left join mic_ccs_artikelpreis c 
     on c.someID = a.someID -- join conidition 
     and c.someField = 'Some Property' -- filtering here 
    ... 

辅助连接条件消除了在where子句中抛出这些记录的风险。再次请参阅my other answer了解更多详情。