Saya mengubah nama kolom Anda group
ke grp
karena group
adalah kata yang dicadangkan
di Postgres dan setiap standar SQL dan tidak boleh digunakan sebagai pengenal.
Saya memahami pertanyaan Anda seperti ini:
Dapatkan dua larik diurutkan dalam urutan yang identik sehingga posisi elemen yang sama sesuai dengan baris yang sama di kedua larik.
Gunakan subkueri atau CTE dan urutkan baris sebelum Anda mengagregasi.
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;
Itu lebih cepat daripada menggunakan ORDER BY
individu klausa dalam fungsi agregat
array_agg()
seperti @Mosty menunjukkan
(dan yang telah ada sejak PostgreSQL 9.0). Mosty juga menafsirkan pertanyaan Anda secara berbeda dan menggunakan alat yang tepat untuk interpretasinya.
Apakah ORDER BY
dalam brankas subquery?
Jadi ya, contoh aman.
Tanpa subkueri
Jika Anda benar-benar membutuhkan solusi tanpa subquery , Anda dapat:
SELECT id
, array_agg(grp ORDER BY grp)
, array_agg(dt ORDER BY grp, dt)
FROM tbl
GROUP BY id;
Perhatikan ORDER BY grp, dt
. Saya mengurutkan berdasarkan dt
selain memutuskan hubungan dan membuat urutan sortir menjadi tidak ambigu. Tidak perlu untuk grp
, meskipun.
Ada juga cara yang sama sekali berbeda untuk melakukan ini, dengan fungsi jendela :
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;
Perhatikan DISTINCT ON (id)
bukan hanya DISTINCT
yang menghasilkan hasil yang sama tetapi bekerja lebih cepat dengan urutan besarnya karena kita tidak memerlukan pengurutan tambahan.
Saya menjalankan beberapa tes dan ini hampir secepat dua solusi lainnya. Seperti yang diharapkan, versi subquery masih tercepat. Uji dengan EXPLAIN ANALYZE
untuk melihat sendiri.