Rumah > pangkalan data > tutorial mysql > Bagaimana untuk Mengumpul Berbilang Tatasusunan dengan Cekap dalam Satu Pertanyaan SQL?

Bagaimana untuk Mengumpul Berbilang Tatasusunan dengan Cekap dalam Satu Pertanyaan SQL?

DDD
Lepaskan: 2024-12-29 02:01:11
asal
121 orang telah melayarinya

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

Panggilan berbilang array_agg() dalam Satu Pertanyaan: Mengagregatkan Tatasusunan Bersarang

Dalam bidang pangkalan data hubungan, situasi timbul apabila berbilang tatasusunan perlu diagregatkan dalam satu pertanyaan. Ini boleh menjadi tugas yang sukar, terutamanya apabila terdapat cantuman yang terlibat.

Isunya

Cabaran datang apabila cuba mengagregat tatasusunan daripada jadual berbeza melalui berbilang cantuman. Tatasusunan yang terhasil mungkin mengandungi pendua dan ketidakkonsistenan yang tidak diperlukan. Sebagai contoh, anda mungkin mempunyai jadual pekerja dengan berbilang alamat (alamat) dan hari bekerja (hari bekerja).

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
Salin selepas log masuk

Pertanyaan ini menghasilkan susunan nama jalan dan hari bekerja, tetapi ia menduplikasi nilai beberapa kali.

Penyelesaian: Mengagregatkan Dahulu

Kunci untuk menyelesaikan masalah ini isu adalah untuk mengagregat tatasusunan sebelum melakukan gabungan. Dengan mengagregatkan dahulu, anda menghalang baris daripada mendarab secara tidak perlu.

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;
Salin selepas log masuk

Dalam pertanyaan ini, pengagregatan alamat dilakukan dalam subkueri sebelum menyertainya dengan jadual hari bekerja. Ini memastikan bahawa hanya satu set nama jalan dan hari bekerja dikaitkan dengan setiap pekerja.

Sebagai alternatif: Subkueri Berkorelasi dan JOIN LATERAL

Untuk penapisan terpilih pada pekerja, berkorelasi subqueries atau JOIN LATERAL (dalam Postgres 9.3 atau lebih baru) boleh bekerja:

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
Salin selepas log masuk

JOIN LATERAL juga boleh digunakan dalam Postgres:

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
Salin selepas log masuk

Pertanyaan ini akan mengekalkan semua pekerja yang layak dalam keputusan.

Atas ialah kandungan terperinci Bagaimana untuk Mengumpul Berbilang Tatasusunan dengan Cekap dalam Satu Pertanyaan SQL?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

sumber:php.cn
Kenyataan Laman Web ini
Kandungan artikel ini disumbangkan secara sukarela oleh netizen, dan hak cipta adalah milik pengarang asal. Laman web ini tidak memikul tanggungjawab undang-undang yang sepadan. Jika anda menemui sebarang kandungan yang disyaki plagiarisme atau pelanggaran, sila hubungi admin@php.cn
Tutorial Popular
Lagi>
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan