在单个查询中组合多个 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
结论
通过实现这些方法,您可以避免行乘法并获得所需的结果,这是一个地址数组和每个员工的一系列工作日。这些解决方案可确保数据正确聚合并正确合并,从而无需额外的过滤或后处理。
以上是在单个 SQL 查询中组合多个 `array_agg()` 调用时如何避免冗余数据?的详细内容。更多信息请关注PHP中文网其他相关文章!