2017-09-18 1 views
0

Ich bin derzeit mit dem folgenden Problem konfrontiert: Ich habe 3 Tabellen, ich brauche Informationen von und diese beiden Joins sind eins zu viele. Aus irgendeinem Grunde zweiter Verbindung erstellt Duplikate von Zeilen und als Folge zweiter Rückgabewert wird verkorksteSQL doppelte Zeilen mit mehreren linken Joins

SELECT aa.id, sum(bb.count), count(DISTINCT cc.id) 
FROM aaaa aa 
LEFT JOIN bbbb bb ON bb.aa_id = aa.id 
LEFT JOIN cccc cc ON cc.bb_id = bb.id 
GROUP BY aa.id 

Gibt es einen Weg, um die richtige Summe zu erhalten (bb.count wird durch die Menge der zweiten Join Zeilen multipliziert) von bb.count ohne weitere Abfrage? In dem Moment, in dem ich den zweiten Linksbündel entferne, ist alles in Ordnung, leider brauche ich es für den dritten Rückgabewert und kann sie nicht gruppieren, ohne doppelte Zeilen im Ergebnis zu erzeugen.

Lets sagen, es

bb1.count = 9 
bb2.count = 5 

ist Und es gibt zwei Zeilen, in denen cc.bb_id = bb1.id Das Ergebnis I erhalten 23 statt 14.

+0

ein minimal funktionierendes Beispiel? .. –

Antwort

2

Sie Aggregat Fanout in der obigen Abfrage erfahren.

Dies geschieht, weil es

  • entweder eine 1-1 oder 1-N Verknüpfung zwischen aaa & bbb
  • gibt es eine 1-N Verbindung zwischen bbb & ccc

The Letzter Join erzeugt M Duplikate für Zeilen, die in bbb existieren, wenn sie über den Join zumit M Zeilen verbunden sind

Um den Fehler zu beheben, teilen Sie die Abfrage in zwei CTEs auf & verbinden Sie das Ergebnis.

WITH agg_bb AS (
SELECT aa.id, sum(bb.count) 
FROM aaaa aa 
LEFT JOIN bbbb bb ON bb.aa_id = aa.id 
GROUP BY aa.id 
) 
, agg_cc AS (SELECT aa.id, count(DISTINCT cc.id) 
FROM aaaa aa 
LEFT JOIN bbbb bb ON bb.aa_id = aa.id 
LEFT JOIN cccc cc ON cc.bb_id = bb.id 
GROUP BY aa.id 
) 
SELECT * FROM agg_bb JOIN agg_cc USING (id) 

Im Allgemeinen Fan-outs zu vermeiden, gilt nur Aggregat Operationen auf die Spalten von der äußersten rechten Beziehung in einer Reihe von Joins. Wenn Sie Spalten aus den mittleren Tabellen zusammenfassen, teilen Sie die Abfrage wie oben beschrieben auf. Nur die folgenden Funktionen sind in einem Fan Out unveränderlich: COUNT DISTINCT, MIN

+0

Vielen Dank, Sie haben gerade meinen Tag gerettet! – Rauno

Verwandte Themen