在单个查询中解析多个 array_agg() 调用
在处理涉及数组的多个联接时,必须了解它们对结果。在本例中,原始查询尝试提取每个员工的地址和工作日的数组。然而,由于多次联接而导致意外的行相乘,从而导致聚合不正确。
解决方案 1:先聚合,后加入
要解决此问题,有效的方法是在加入子查询之前聚合子查询中的数据。通过将聚合与联接分离,避免了行乘法的问题:
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;
解决方案 2:关联子查询或 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
或者,LATERAL Postgres 9.3 或更高版本中可以使用联接:
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中文网其他相关文章!