首頁 > 資料庫 > mysql教程 > 如何在單一 SQL 查詢中高效聚合多個陣列?

如何在單一 SQL 查詢中高效聚合多個陣列?

DDD
發布: 2024-12-29 02:01:11
原創
122 人瀏覽過

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

單一查詢中多次呼叫array_agg():聚合巢狀陣列

在關聯式資料庫領域,會出現多個陣列的情況需要聚合在單一查詢中。這可能是一項棘手的任務,尤其是在涉及聯接時。

問題

嘗試透過多個聯結聚合來自不同表的陣列時會遇到挑戰。產生的陣列可能包含不必要的重複和不一致。例如,您可能有一個包含多個地址(地址)和工作日(工作日)的員工表。

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
登入後複製

此查詢會產生一組街道名稱和工作日,但它會重複值

解決方案:先聚合

解決這個問題的關鍵是在執行連線之前聚合數組。透過先聚合,可以防止行不必要地增加。

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;
登入後複製

在此查詢中,位址聚合在子查詢中完成,然後再與工作日表連接。這確保只有一組街道名稱和工作日與每個員工關聯。

或:關聯子查詢和JOIN LATERAL

對於員工的選擇性過濾,關聯子查詢或JOIN LATERAL(在Postgres 9.3 或更高版本中)可以就業:

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
登入後複製

JOIN LATERAL 也可以在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
登入後複製

這些查詢將在結果中保留所有符合資格的員工。

以上是如何在單一 SQL 查詢中高效聚合多個陣列?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板