Heim > Datenbank > MySQL-Tutorial > Wie kann man mehrere Arrays effizient in einer einzigen SQL-Abfrage aggregieren?

Wie kann man mehrere Arrays effizient in einer einzigen SQL-Abfrage aggregieren?

DDD
Freigeben: 2024-12-29 02:01:11
Original
121 Leute haben es durchsucht

How to Efficiently Aggregate Multiple Arrays in a Single SQL Query?

Mehrere array_agg()-Aufrufe in einer einzigen Abfrage: Aggregieren verschachtelter Arrays

Im Bereich relationaler Datenbanken kommt es vor, dass mehrere Arrays vorhanden sind müssen in einer einzigen Abfrage zusammengefasst werden. Dies kann eine knifflige Aufgabe sein, insbesondere wenn Joins beteiligt sind.

Das Problem

Die Herausforderung entsteht, wenn versucht wird, Arrays aus verschiedenen Tabellen über mehrere Joins zusammenzufassen. Das resultierende Array kann unnötige Duplikate und Inkonsistenzen enthalten. Beispielsweise verfügen Sie möglicherweise über eine Tabelle mit Mitarbeitern mit mehreren Adressen (Adresse) und Arbeitstagen (Arbeitstage).

SELECT name, age, array_agg(ad.street), arrag_agg(wd.day)
FROM employees e
JOIN address ad ON e.id = ad.employeeid
JOIN workingdays wd ON e.id = wd.employeeid
GROUP BY name, age
Nach dem Login kopieren

Diese Abfrage führt zu einem Array von Straßennamen und Arbeitstagen, dupliziert jedoch die Werte mehrmals.

Die Lösung: Zuerst aggregieren

Der Schlüssel zur Lösung dieses Problems besteht darin, die Arrays vorher zu aggregieren Durchführen der Verknüpfung. Indem Sie zuerst aggregieren, verhindern Sie, dass sich die Zeilen unnötig vervielfachen.

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  -- PK covers whole row
   ) e
JOIN   workingdays wd ON wd.employeeid = e.id
GROUP  BY e.id, e.name, e.age;
Nach dem Login kopieren

Bei dieser Abfrage erfolgt die Adressaggregation in einer Unterabfrage, bevor sie mit der Tabelle „Arbeitstage“ verknüpft wird. Dadurch wird sichergestellt, dass jedem Mitarbeiter nur ein Satz von Straßennamen und Arbeitstagen zugeordnet ist.

Alternativ: Korrelierte Unterabfragen und JOIN LATERAL

Zur selektiven Filterung nach Mitarbeitern, korreliert Unterabfragen oder JOIN LATERAL (in Postgres 9.3 oder höher) können sein beschäftigt:

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';  -- very selective
Nach dem Login kopieren

JOIN LATERAL kann auch in Postgres verwendet werden:

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';  -- very selective
Nach dem Login kopieren

Diese Abfragen behalten alle qualifizierten Mitarbeiter im Ergebnis.

Das obige ist der detaillierte Inhalt vonWie kann man mehrere Arrays effizient in einer einzigen SQL-Abfrage aggregieren?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage