首頁 >資料庫 >mysql教程 >在 SQL 連線中使用多個「array_agg()」呼叫時如何避免行乘法?

在 SQL 連線中使用多個「array_agg()」呼叫時如何避免行乘法?

Patricia Arquette
Patricia Arquette原創
2024-12-31 14:26:14145瀏覽

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

在單一查詢中解析多個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中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn