2016-03-30 6 views
1

Ich bin zwei Tabellen auf drei Felder beitreten. Das Problem, das ich habe, ist, dass ich eine Standardreihe von Tabelle b verwenden muss, wenn a.baz nicht in b.baz ist. Das Problem ist, einige haben eine Übereinstimmung in b, haben aber auch einen Standard und das verursacht ein Cross-Produkt, das ich nicht will.Verbinden mit Standardwerten, aber kein Cross-Produkt wollen

select a.foo, a.bar, a.baz, b.fee, b.fie 
from a 
join b 
on a.foo = b.foo 
and a.bar = b.bar 
and ((a.baz = b.baz) or b.baz = 'DEFAULT') 

Stromausgang:

foo bar baz fee fie 
bob doe NYC 500 200 
bob doe DEFUALT 100 100 
john doe DEFAULT 100 100 
jane doe NYC 500 500 

gewünschten Ausgangs:

foo bar baz fee fie 
bob doe NYC 500 200 
john doe DEFAULT 100 100 
jane doe NYC 500 500 

Probendaten:

a: foo bar baz bob doe NYC john doe NYC jane doe NYC

b: foo bar baz fee fie bob doe NYC 500 200 bob doe DEFAULT 100 100 john doe CHI 300 200 john doe DEFAULT 100 100 jane doe NYC 500 100

+2

können Sie einige Beispieldaten aus den Tabellen anzeigen? –

+0

Einige Beispieldaten hinzugefügt. – SparkeyG

+1

Das Ergebnis, das Sie erhalten, ist kein Cross-Produkt. Ich denke, Ihre aktuelle Ausgabe ist korrekt, mit den Bedingungen in Frage. –

Antwort

2

Sie haben eine NOT EXISTS so hinzuzufügen, wie die b Aufzeichnung auszuschließen baz = 'DEFAULT' mit, wenn eine Übereinstimmung a.baz = b.baz auch vorhanden:

select a.foo, a.bar, a.baz, b.baz, b.fee, b.fie 
from a 
join b 
on a.foo = b.foo and a.bar = b.bar and ((a.baz = b.baz) OR b.baz = 'DEFAULT') 
where not exists (select 1 
        from b as b1 
        where a.foo = b1.foo and 
         a.bar = b1.bar and 
         b.baz = 'DEFAULT' and 
         b1.baz = a.baz) 

Demo here

+0

Danke, das hat den Trick gemacht. – SparkeyG

0

Ihre Anfrage ganz in Ordnung ist, wie es bereits die Zeilen enthält Sie wollen. Jetzt müssen Sie die unerwünschten Zeilen entfernen. Sie tun dies, indem Sie Ihre Matches klassifizieren und nur das bessere Match halten. Dies kann mit ROW_NUMBER getan werden, um die bessere Bilanz Zeilennummer geben 1.

select foo, bar, abaz, bbaz, fee, fie 
from 
(
    select 
    a.foo, a.bar, a.baz as abaz, b.baz as bbaz, b.fee, b.fie, 
    row_number() over (partition by a.foo, a.bar 
         order by case when b.baz = 'DEFAULT' then 2 else 1 end) as rn 
    from a 
    join b on b.foo = a.foo 
     and b.bar = a.bar 
     and b.baz in (a.baz, 'DEFAULT') 
) ranked 
where rn = 1; 
0

Hier ist eine weitere einfache Möglichkeit, dies mit Außen zu lösen verbindet:

select 
    a.foo, 
    a.bar, 
    case when b.baz is null then d.baz else b.baz end as baz, 
    case when b.baz is null then d.fee else b.fee end as fee, 
    case when b.baz is null then d.fie else b.fie end as fie 
from a 
left join b on b.foo = a.foo and b.bar = a.bar and b.baz = a.baz 
left join b d on d.foo = a.foo and d.bar = a.bar and d.baz = 'DEFAULT'; 

Wenn Gebühr und fie sind keine Nullwerte enthalten, Sie kann dies vereinfachen:

select 
    a.foo, 
    a.bar, 
    coalesce(b.baz, d.baz) as baz, 
    coalesce(b.fee, d.fee) as fee, 
    coalesce(b.fie, d.fie) as fie 
from a 
left join b on b.foo = a.foo and b.bar = a.bar and b.baz = a.baz 
left join b d on d.foo = a.foo and d.bar = a.bar and d.baz = 'DEFAULT'; 
Verwandte Themen