在單一查詢中組合多個array_agg() 呼叫
在查詢中,您遇到多個array_agg() 呼叫返回冗餘餘的問題數據。由於多個聯接而出現重複行會導致不期望的結果。為了解決這個問題,我們可以探索幾種從一開始就避免行乘法的方法。
解決方案 1:先聚合,稍後加入
一種有效的方法是聚合在執行連接之前子查詢中的資料。這可確保每個員工記錄都是唯一的,從而防止行乘法。修改後的查詢如下所示:
SELECT e.id, 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;
解決方案2:關聯子查詢/JOIN LATERAL
另一種方法是在PostgreSQL 9.3 中利用關聯子查詢或JOIN LATERAL或稍後。此技術可讓您在主查詢中檢索每位員工的聚合資料。修改後的查詢將是:
相關子查詢:
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橫向:
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
JOIN橫向:
結論透過實現這些方法,您可以避免行乘法並獲得所需的結果,這是一個位址陣列和每個員工的一系列工作日。這些解決方案可確保資料正確聚合並正確合併,從而無需額外的過濾或後處理。以上是在單一 SQL 查詢中組合多個 `array_agg()` 呼叫時如何避免冗餘資料?的詳細內容。更多資訊請關注PHP中文網其他相關文章!