Vermeiden Sie mehrere verschachtelte Aggregate in PostgreSQL-Abfragen
Mehrere array_agg()-Aufrufe in einer einzelnen Abfrage können zu unerwarteten Ergebnissen führen, wie in der Abbildung gezeigt Beispiel zur Verfügung gestellt. Dieses Problem entsteht durch die Verknüpfung von Tabellen mit mehreren Zeilen, wodurch effektiv ein kartesisches Produkt entsteht. Um dies zu beheben, ziehen Sie die folgenden Strategien in Betracht:
Zuerst aggregieren, später verbinden
Aggregieren Sie die Daten aus jeder Tabelle separat in einer Unterabfrage, bevor Sie sie zusammenführen. Dadurch wird sichergestellt, dass Sie über einen eindeutigen Satz von Zeilen aggregieren:
SELECT e.id, e.name, e.age, e.streets, array_agg(wd.day) AS days FROM ( SELECT e.id, e.name, e.age, array_agg(ad.street) AS streets FROM employees e JOIN address ad ON ad.employeeid = e.id GROUP BY e.id ) e JOIN workingdays wd ON wd.employeeid = e.id GROUP BY e.id, e.name, e.age;
Korrelierte Unterabfragen oder JOIN LATERAL
Verwenden Sie korrelierte Unterabfragen oder JOIN LATERAL, um Daten für jede Zeile zu aggregieren einzeln, was selektive Filter ermöglicht:
Korreliert Unterabfragen:
SELECT name, age , (SELECT array_agg(street) FROM address WHERE employeeid = e.id) AS streets , (SELECT array_agg(day) FROM workingdays WHERE employeeid = e.id) AS days FROM employees e WHERE e.namer = 'peter';
JOIN LATERAL:
SELECT e.name, e.age, a.streets, w.days FROM employees e LEFT JOIN LATERAL ( SELECT array_agg(street) AS streets FROM address WHERE employeeid = e.id GROUP BY 1 ) a ON true LEFT JOIN LATERAL ( SELECT array_agg(day) AS days FROM workingdays WHERE employeeid = e.id GROUP BY 1 ) w ON true WHERE e.name = 'peter';
Diese Methoden verhindern unnötige Zeilenduplizierung und liefern die gewünschten Array-Aggregationsergebnisse.
Das obige ist der detaillierte Inhalt vonWie vermeide ich unerwartete Ergebnisse aus mehreren verschachtelten „array_agg()'-Aufrufen in PostgreSQL?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!