Запрос комбинаций JSON возвращает нечетные результаты
Это продолжение question. Кажется, я столкнулся с краевым случаем, и я не понимаю, почему я получаю неправильные результаты. Используя данные из связанного вопроса,
Я могу сгруппировать их в комбинации, которые используют один и тот же альбом, src и background.
Например, используя эти данные:
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":"background.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"}')
;
и это запрос:
SELECT distinct array_agg(distinct 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->>'src'
ORDER BY count(*) DESC
LIMIT 5;
Я получаю эти результаты, которые неверны:
ids | ct
---------+----
{1,2,3} | 3
{1,3} | 2
{2} | 1
{4} | 1
Я хочу, чтобы это
ids | ct
---------+----
{1,3} | 2
{2} | 1
{4} | 1
Если я изменяю значения background
так, чтобы они менялись, то он работает так, как ожидалось, но подсчеты все еще отключены. Так что я собираюсь, группировка background
может быть причиной этой проблемы. Но я не знаю почему. Я могу обойтись без учета, мне просто нужны идентификаторы, сгруппированные для соответствия комбинациям, которые используют один и тот же файл, альбом и фон.
Edit
Мне пришлось изменить свой вопрос. Оказывается, у моих образцов данных была ошибка, и я не получал правильных результатов. Поэтому я ищу запрос, который работает, если это возможно.
Ответы
Ответ 1
Добрый человек из IRC-канала Postgresql помог найти ответ и обработать правильный запрос. Кредит - это его, а не мой.
Он помог понять, что альбомы и srcs должны быть добавлены в массивы для сравнения. Например:
SELECT array_agg(rep_id), count(*) AS ct
FROM (SELECT rep_id,
data->>'background' as background,
array_agg(o->>'album' order by o->>'album') as albums,
array_agg(o->>'src' order by o->>'album') as srcs
FROM reports r,
json_array_elements(r.data->'objects') o
GROUP BY rep_id) s
GROUP BY background, albums, srcs
ORDER BY count(*) DESC
LIMIT 5;
Я не знаю, это лучший способ сделать это, но он работает. Предложения приветствуются.
Ответ 2
Прежде всего, у вас есть опечатка, измените 'scr'
на 'src'
. Но ваш запрос правильный, просто взгляните на свой запрос без группировки:
select
r.rep_id, r.data->>'background' as background, o->>'album' as album, o->>'src' as src
from reports r, json_array_elements(r.data->'objects') o;
------------------------------------------------------------
REP_ID BACKGROUND ALBUM SRC
1 background.png 1 fooA.png
1 background.png 2 barB.png
2 background.png 2 barB.png
2 background.png 2 barB.png
Ответ 3
Если вы посчитаете отличным от rep_id, вы получите количество строк, в которых произошла уникальная комбинация.
SELECT distinct array_agg(distinct r.rep_id) AS ids, count(distinct r.rep_id) AS ct, array[r.data->>'background', o->>'album', o->>'src'] as combination
FROM reports r
, json_array_elements(r.data->'objects') o
GROUP BY r.data->>'background'
, o->>'album'
, o->>'src'
ORDER BY 2 DESC
Результат для первого набора данных:
ids ct combination
{1,2,3} 3 {background.png,1,fooA.png}
{1,3} 2 {background.png,2,barB.png}
{2} 1 {background.png,2,barC.png}
{4} 1 {backgroundA.png,1,fooA.png}
{4} 1 {backgroundA.png,3,barB.png}
Повторить второй набор данных:
ids ct combination
{1,2} 2 {background.png,2,barB.png}
{1} 1 {background.png,1,fooA.png}