首页 > 数据库 > 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
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板