PostgreSQL
 sql >> Teknologi Basis Data >  >> RDS >> PostgreSQL

Buat dua larik untuk dua bidang, jaga agar susunan susunan larik tetap sinkron (tanpa subkueri)

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?

Manual:

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.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Pilih di mana huruf pertama dalam suatu rentang ( PostgreSQL )

  2. Metode otentikasi PostgreSQL 10 tidak didukung

  3. Gabungkan hasil tabel menjadi kolom (pivot/crosstab?)

  4. Bug dalam mekanisme penguncian PostgreSQL atau kesalahpahaman mekanisme

  5. Bagaimana menerapkan Select For Update di EF Core