Rumah >pangkalan data >tutorial mysql >Bagaimana untuk Mengelakkan Pendaraban Baris Apabila Menggunakan Berbilang Panggilan `array_agg()` dalam SQL Joins?

Bagaimana untuk Mengelakkan Pendaraban Baris Apabila Menggunakan Berbilang Panggilan `array_agg()` dalam SQL Joins?

Patricia Arquette
Patricia Arquetteasal
2024-12-31 14:26:14158semak imbas

How to Avoid Row Multiplication When Using Multiple `array_agg()` Calls in SQL Joins?

Menyelesaikan Panggilan Berbilang array_agg() dalam Satu Pertanyaan

Apabila bekerja dengan berbilang gabungan yang melibatkan tatasusunan, adalah penting untuk memahami kesannya terhadap keputusannya. Dalam kes ini, pertanyaan asal cuba mengekstrak tatasusunan untuk kedua-dua alamat dan hari bekerja untuk setiap pekerja. Walau bagaimanapun, pendaraban baris yang tidak dijangka disebabkan oleh berbilang cantuman membawa kepada pengagregatan yang salah.

Penyelesaian 1: Agregat Dahulu, Sertai Kemudian

Untuk menyelesaikan masalah ini, pendekatan yang berkesan ialah untuk mengagregat data dalam subkueri sebelum menyertainya. Dengan mengasingkan pengagregatan daripada cantuman, isu pendaraban baris dielakkan:

SELECT e.name, e.age, ad.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;

Penyelesaian 2: Subkueri Berkorelasi atau JOIN LATERAL

Untuk penapisan terpilih pada pekerja , subqueries berkorelasi boleh digunakan:

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

Sebagai alternatif, penyertaan LATERAL boleh digunakan dalam Postgres 9.3 atau lebih baru:

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

Pendekatan alternatif ini memastikan bahawa semua pekerja yang layak dikekalkan dalam keputusan, mengelakkan yang sebelumnya isu pendaraban baris.

Atas ialah kandungan terperinci Bagaimana untuk Mengelakkan Pendaraban Baris Apabila Menggunakan Berbilang Panggilan `array_agg()` dalam SQL Joins?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!

Kenyataan:
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