Tôi đã thay đổi tên cột của bạn group
thành grp
bởi vì group
là một từ dành riêng
trong Postgres và mọi tiêu chuẩn SQL và không nên được sử dụng làm định danh.
Tôi hiểu câu hỏi của bạn như thế này:
Sắp xếp hai mảng theo thứ tự sắp xếp giống hệt nhau để vị trí phần tử giống nhau tương ứng với cùng một hàng trong cả hai mảng.
Sử dụng truy vấn con hoặc CTE và sắp xếp các hàng trước khi bạn tổng hợp.
SELECT id, array_agg(grp) AS grp, array_agg(dt) AS dt
FROM (
SELECT *
FROM tbl
ORDER BY id, grp, dt
) x
GROUP BY id;
Đó là nhanh hơn hơn là sử dụng từng ORDER BY
riêng lẻ mệnh đề trong hàm tổng hợp
array_agg()
như @Mosty minh họa
(và đã có từ PostgreSQL 9.0). Mosty cũng diễn giải câu hỏi của bạn theo cách khác và sử dụng các công cụ thích hợp để giải thích.
Là ORDER BY
trong một truy vấn con an toàn?
Vì vậy, có, nó an toàn trong ví dụ.
Không có truy vấn con
Nếu bạn thực sự cần một giải pháp không có truy vấn con , bạn có thể:
SELECT id
, array_agg(grp ORDER BY grp)
, array_agg(dt ORDER BY grp, dt)
FROM tbl
GROUP BY id;
Lưu ý ORDER BY grp, dt
. Tôi sắp xếp theo dt
ngoài việc phá vỡ các mối quan hệ và làm cho thứ tự sắp xếp không rõ ràng. Không cần thiết cho grp
, mặc dù.
Cũng có một cách hoàn toàn khác để thực hiện việc này, với các hàm cửa sổ :
SELECT DISTINCT ON (id)
id
, array_agg(grp) OVER w AS grp
, array_agg(dt) OVER w AS dt
FROM tbl
WINDOW w AS (PARTITION BY id ORDER BY grp, dt
ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING)
ORDER BY id;
Lưu ý DISTINCT ON (id)
thay vì chỉ DISTINCT
tạo ra cùng một kết quả nhưng hoạt động nhanh hơn theo thứ tự cường độ vì chúng tôi không cần sắp xếp thêm.
Tôi đã chạy một số thử nghiệm và điều này gần như nhanh bằng hai giải pháp còn lại. Như mong đợi, phiên bản truy vấn con vẫn nhanh nhất. Kiểm tra với EXPLAIN ANALYZE
để tự mình xem.