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

Hasil pengembalian PostgreSQL ditetapkan sebagai array JSON?

TL;DR

SELECT json_agg(t) FROM t

untuk array objek JSON, dan

SELECT
    json_build_object(
        'a', json_agg(t.a),
        'b', json_agg(t.b)
    )
FROM t

untuk objek array JSON.

Daftar objek

Bagian ini menjelaskan cara menghasilkan larik objek JSON, dengan setiap baris dikonversi menjadi satu objek. Hasilnya terlihat seperti ini:

[{"a":1,"b":"value1"},{"a":2,"b":"value2"},{"a":3,"b":"value3"}]

9.3 dan lebih tinggi

json_agg fungsi menghasilkan hasil ini di luar kotak. Secara otomatis mengetahui cara mengubah inputnya menjadi JSON dan menggabungkannya menjadi array.

SELECT json_agg(t) FROM t

Tidak ada jsonb (diperkenalkan pada 9.4) versi json_agg . Anda dapat menggabungkan baris menjadi sebuah array dan kemudian mengonversinya:

SELECT to_jsonb(array_agg(t)) FROM t

atau gabungkan json_agg dengan pemeran:

SELECT json_agg(t)::jsonb FROM t

Pengujian saya menunjukkan bahwa menggabungkannya ke dalam array terlebih dahulu sedikit lebih cepat. Saya menduga ini karena para pemain harus mengurai seluruh hasil JSON.

9.2

9.2 tidak memiliki json_agg atau to_json fungsi, jadi Anda perlu menggunakan array_to_json yang lebih lama :

SELECT array_to_json(array_agg(t)) FROM t

Anda dapat secara opsional menyertakan row_to_json panggil dalam kueri:

SELECT array_to_json(array_agg(row_to_json(t))) FROM t

Ini mengonversi setiap baris menjadi objek JSON, menggabungkan objek JSON sebagai larik, lalu mengonversi larik menjadi larik JSON.

Saya tidak dapat melihat perbedaan performa yang signifikan di antara keduanya.

Objek daftar

Bagian ini menjelaskan cara menghasilkan objek JSON, dengan setiap kunci menjadi kolom dalam tabel dan setiap nilai menjadi larik dari nilai kolom. Hasilnya seperti ini:

{"a":[1,2,3], "b":["value1","value2","value3"]}

9.5 dan lebih tinggi

Kita dapat memanfaatkan json_build_object fungsi:

SELECT
    json_build_object(
        'a', json_agg(t.a),
        'b', json_agg(t.b)
    )
FROM t

Anda juga dapat menggabungkan kolom, membuat satu baris, lalu mengubahnya menjadi objek:

SELECT to_json(r)
FROM (
    SELECT
        json_agg(t.a) AS a,
        json_agg(t.b) AS b
    FROM t
) r

Perhatikan bahwa aliasing array mutlak diperlukan untuk memastikan bahwa objek memiliki nama yang diinginkan.

Mana yang lebih jelas adalah masalah pendapat. Jika menggunakan json_build_object fungsi, saya sangat menyarankan menempatkan satu pasangan kunci/nilai pada baris untuk meningkatkan keterbacaan.

Anda juga dapat menggunakan array_agg sebagai pengganti json_agg , tetapi pengujian saya menunjukkan bahwa json_agg sedikit lebih cepat.

Tidak ada jsonb versi json_build_object fungsi. Anda dapat menggabungkan menjadi satu baris dan mengonversi:

SELECT to_jsonb(r)
FROM (
    SELECT
        array_agg(t.a) AS a,
        array_agg(t.b) AS b
    FROM t
) r

Tidak seperti kueri lain untuk hasil seperti ini, array_agg tampaknya sedikit lebih cepat saat menggunakan to_jsonb . Saya menduga ini karena penguraian overhead dan memvalidasi hasil JSON dari json_agg .

Atau Anda dapat menggunakan pemeran eksplisit:

SELECT
    json_build_object(
        'a', json_agg(t.a),
        'b', json_agg(t.b)
    )::jsonb
FROM t

to_jsonb versi memungkinkan Anda untuk menghindari pemeran dan lebih cepat, menurut pengujian saya; sekali lagi, saya menduga ini karena overhead parsing dan validasi hasilnya.

9,4 dan 9,3

json_build_object function baru untuk 9.5, jadi Anda harus menggabungkan dan mengonversi ke objek di versi sebelumnya:

SELECT to_json(r)
FROM (
    SELECT
        json_agg(t.a) AS a,
        json_agg(t.b) AS b
    FROM t
) r

atau

SELECT to_jsonb(r)
FROM (
    SELECT
        array_agg(t.a) AS a,
        array_agg(t.b) AS b
    FROM t
) r

tergantung pada apakah Anda ingin json atau jsonb .

(9.3 tidak memiliki jsonb .)

9.2

Di 9.2, bahkan tidak to_json ada. Anda harus menggunakan row_to_json :

SELECT row_to_json(r)
FROM (
    SELECT
        array_agg(t.a) AS a,
        array_agg(t.b) AS b
    FROM t
) r

Dokumentasi

Temukan dokumentasi untuk fungsi JSON di fungsi JSON.

json_agg ada di halaman fungsi agregat.

Desain

Jika kinerja penting, pastikan Anda membandingkan kueri Anda dengan skema dan data Anda sendiri, daripada memercayai pengujian saya.

Apakah itu desain yang bagus atau tidak sangat tergantung pada aplikasi spesifik Anda. Dalam hal pemeliharaan, saya tidak melihat ada masalah khusus. Ini menyederhanakan kode aplikasi Anda dan berarti lebih sedikit yang harus dipertahankan di bagian aplikasi tersebut. Jika PG dapat memberikan hasil yang Anda butuhkan di luar kotak, satu-satunya alasan yang dapat saya pikirkan untuk tidak menggunakannya adalah pertimbangan kinerja. Jangan menemukan kembali roda dan segalanya.

Null

Fungsi agregat biasanya mengembalikan NULL ketika mereka beroperasi lebih dari nol baris. Jika memungkinkan, Anda mungkin ingin menggunakan COALESCE untuk menghindari mereka. Beberapa contoh:

SELECT COALESCE(json_agg(t), '[]'::json) FROM t

Atau

SELECT to_jsonb(COALESCE(array_agg(t), ARRAY[]::t[])) FROM t

Kredit untuk Hannes Landeholm karena menunjukkan hal ini



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bagaimana cara membuat enum Java &Postgres bekerja sama untuk pembaruan?

  2. SQL, Postgres OIDs, Apa itu dan mengapa berguna?

  3. Menggunakan klausa KECUALI di PostgreSQL

  4. hilangkan nilai array duplikat di postgres

  5. Salin struktur tabel ke tabel baru