Rolf B: IF Abfrage zur Auswahl von verschiedenen LEFT JOIN

Beitrag lesen

Hallo Manon,

den ORDER BY setzt Du ans Ende. Der wirkt auf die UNION, nicht nur auf einen SELECT.

Aber wenn Du bei der LEFT JOIN Kette bleibst, dann solltest die JOINs für Typ=1 und Typ=2 zusammenlegen.

SELECT a.bla1, a.bla2, a.bla3, ab.foo, ab.bar, cc.foo, cc.bar
FROM blablabla a
     LEFT JOIN data_text ab
             ON (a.typ=1 OR a.typ=2) AND ab.id_field=a.id
     LEFT JOIN data_calc cc
             ON a.typ=3 AND cc.id_field=a.id

Die Frage ist, worum es Dir bei der Optimierung geht. Findest Du die LEFT JOIN Kette einfach unschön? Oder ist es Dir wichtig, die Spalten ab.foo und cc.foo sowie ab.bar und cc.bar zu einer Spalte zusammenzulegen?

Zusammenlegen kannst Du sie mit der COALESCE-Funktion, die liefert nämlich den ersten nicht-NULL Wert ihrer Argumente.

SELECT a.bla1, a.bla2, a.bla3,
       COALESCE(ab.foo, cc.foo), 
       COALESCE(ab.bar, cc.bar)
FROM blablabla a
     LEFT JOIN data_text ab
             ON (a.typ=1 OR a.typ=2) AND ab.id_field=a.id
     LEFT JOIN data_calc cc
             ON a.typ=3 AND cc.id_field=a.id

Das funktioniert für diese Query, weil über die Abfrage des Typs immer nur einer der beiden LEFT JOIN einen Treffer liefern kann. COALESCE ist hier die kompakte Alternative zu CASE. Mit CASE wird es schon recht geschwätzig (ich halte es noch knapp, weil ich Typ=1 und Typ=2 im ELSE abhandle):

SELECT a.bla1, a.bla2, a.bla3,
       CASE a.typ WHEN 3 cc.foo ELSE ab.foo END, 
       CASE a.typ WHEN 3 cc.bar ELSE ab.bar END
FROM blablabla a
     LEFT JOIN data_text ab
               ON (a.typ=1 OR a.typ=2) AND ab.id_field=a.id
     LEFT JOIN data_calc cc 
               ON a.typ=3 AND cc.id_field=a.id

Okay, der UNION ALL ist noch geschwätziger. Aber nach meiner Meinung ist es dann klarer, was passiert. Wie es mit der Performance aussieht, muss man wie gesagt messen. Da hängt viel am Datenvolumen und an vorhandenen Indexen.

Rolf

--
sumpsi - posui - clusi