避免在PostgreSQL 查詢中使用多個巢狀聚合
單一查詢中的多個array_agg() 呼叫可能會導致意外結果,如提供的範例。此問題是由於連接具有多行的表而有效地創建笛卡爾積而引起的。要修正此問題,請考慮以下策略:
先聚合,稍後加入
在連接之前在子查詢中分別聚合每個表中的資料。這可確保您聚合一組唯一的行:
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 ) e JOIN workingdays wd ON wd.employeeid = e.id GROUP BY e.id, e.name, e.age;
相關子查詢或 JOIN LATERAL
使用相關子查詢或 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';
JOIN LATERAL:
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';
這些方法可以防止不必要的行重複並提供所需的陣列聚合結果。
以上是如何避免 PostgreSQL 中多個巢狀 `array_agg()` 呼叫產生意外結果?的詳細內容。更多資訊請關注PHP中文網其他相關文章!