Đưa ra bảng này (mà lẽ ra bạn phải cung cấp trong một biểu mẫu như thế này):
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"}')
;
Bản ghi JSON thuộc loại nổi tiếng, có thể dịch được
Sử dụng json_populate_recordset()
để bỏ ghi chú tập bản ghi "objects"
. Hàm yêu cầu một kiểu hàng đã đăng ký để xác định tên và kiểu dữ liệu của các cột kết quả. Đối với mục đích của bản trình diễn này hoặc nói chung cho các truy vấn đặc biệt, bảng tạm thời được mô hình hóa sau "objects"
cung cấp giống nhau:
CREATE TEMP TABLE obj(album int, src text, pos text);
Để tìm 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;
Mỗi đối tượng đều được tính, bất kể từ cùng một hàng hay không. Bạn đã không xác định làm thế nào để xử lý điều đó một cách chính xác. Do đó, rep_id
có thể bật lên nhiều lần trong mảng ids
. Thêm DISTINCT
thành array_agg()
để gấp các bản sao có thể có. Số lượng ct
có thể lớn hơn thì độ dài của mảng ids
trong trường hợp này.
Yêu cầu Postgres 9.3 cho các hàm và toán tử JSON và JOIN LATERAL
ngầm .
Bản ghi JSON thuộc loại không xác định hoặc không thể dịch được
json_array_elements()
chỉ cần giải nén mảng json mà không cần chuyển đổi kết quả thành một hàng SQL. Truy cập các trường riêng lẻ với toán tử JSON tương ứng.
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;