Diberikan tabel ini (yang seharusnya Anda berikan dalam bentuk seperti ini):
CREATE TABLE reports (rep_id int primary key, data json);
INSERT INTO reports (rep_id, data)
VALUES
(1, '{"objects":[{"album": 1, "src":"fooA.png", "pos": "top"}, {"album": 2, "src":"barB.png", "pos": "top"}], "background":"background.png"}')
, (2, '{"objects":[{"album": 1, "src":"fooA.png", "pos": "top"}, {"album": 2, "src":"barC.png", "pos": "top"}], "background":"bacakground.png"}')
, (3, '{"objects":[{"album": 1, "src":"fooA.png", "pos": "middle"},{"album": 2, "src":"barB.png", "pos": "middle"}],"background":"background.png"}')
, (4, '{"objects":[{"album": 1, "src":"fooA.png", "pos": "top"}, {"album": 3, "src":"barB.png", "pos": "top"}], "background":"backgroundA.png"}')
;
Catatan JSON dari jenis yang terkenal dan dapat diterjemahkan
Gunakan json_populate_recordset()
untuk menghapus kumpulan "objects"
.Fungsi ini membutuhkan tipe baris terdaftar untuk menentukan nama dan tipe data kolom yang dihasilkan. Untuk tujuan demo ini atau umumnya untuk kueri ad-hoc, tabel sementara dimodelkan setelah "objects"
memberikan hal yang sama:
CREATE TEMP TABLE obj(album int, src text, pos text);
Untuk menemukan the top 3 most common combinations
... of entries that have the same album, src, and background
:
SELECT array_agg(r.rep_id) AS ids, count(*) AS ct
FROM reports r
, json_populate_recordset(null::obj, r.data->'objects') o
GROUP BY r.data->>'background'
, o.album
, o.scr
ORDER BY count(*) DESC
LIMIT 3;
Setiap objek dihitung, tidak peduli apakah dari baris yang sama atau tidak. Anda tidak mendefinisikan bagaimana menanganinya dengan tepat. Akibatnya, rep_id
dapat muncul beberapa kali dalam larik ids
. Tambahkan DISTINCT
ke array_agg()
untuk melipat kemungkinan duplikat. Hitungan ct
bisa lebih besar dari panjang larik ids
dalam hal ini.
Memerlukan Postgres 9.3 untuk fungsi dan operator JSON dan JOIN LATERAL
implisit .
Data JSON dari jenis yang tidak diketahui atau tidak dapat diterjemahkan
json_array_elements()
hapus saja array json tanpa mengubah hasilnya menjadi baris SQL. Akses masing-masing bidang dengan operator JSON yang sesuai.
SELECT array_agg(r.rep_id) AS ids, count(*) AS ct
FROM reports r
, json_array_elements(r.data->'objects') o
GROUP BY r.data->>'background'
, o->>'album'
, o->>'scr'
ORDER BY count(*) DESC
LIMIT 3;