Home >Database >Mysql Tutorial >How to Avoid Row Multiplication When Using Multiple `array_agg()` Calls in SQL Joins?

How to Avoid Row Multiplication When Using Multiple `array_agg()` Calls in SQL Joins?

Patricia Arquette
Patricia ArquetteOriginal
2024-12-31 14:26:14144browse

How to Avoid Row Multiplication When Using Multiple `array_agg()` Calls in SQL Joins?

Resolving Multiple array_agg() Calls in a Single Query

When working with multiple joins involving arrays, it is essential to understand their impact on the results. In this case, the original query attempts to extract arrays for both addresses and working days for each employee. However, the unexpected multiplication of rows due to multiple joins leads to incorrect aggregation.

Solution 1: Aggregate First, Join Later

To resolve this, an effective approach is to aggregate the data in subqueries before joining them. By separating the aggregation from the joins, the issue of row multiplication is avoided:

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;

Solution 2: Correlated Subqueries or JOIN LATERAL

For selective filtering on employees, correlated subqueries can be utilized:

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

Alternatively, LATERAL joins can be employed in Postgres 9.3 or later:

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

These alternative approaches ensure that all qualifying employees are retained in the result, avoiding the previous issue of row multiplication.

The above is the detailed content of How to Avoid Row Multiplication When Using Multiple `array_agg()` Calls in SQL Joins?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn