查询JSON组合会返回奇怪的结果

时间:2015-01-08 19:35:19

标签: sql json postgresql postgresql-9.3

这是此question的后续内容。我似乎遇到了一个边缘案例,我不明白为什么我得到了错误的结果。使用链接问题的数据, 我可以将它们分组为使用相同专辑,src和背景的组合。

例如,使用此数据:

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的分组可能是问题的原因。但我不知道为什么。我可以不用计数,我只需要为使用相同文件,专辑和背景的匹配组合分组ID。

修改 我不得不编辑我的问题。事实证明我的样本数据有错误,我从来没有得到正确的结果。所以我正在寻找一个可行的查询。

3 个答案:

答案 0 :(得分:1)

来自Postgresql的IRC频道的善良人士帮助找到了答案并制作了正确的查询。信用实际上是他的,而不是我的。

他帮助意识到应该将专辑和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;

我不知道这是否是最佳方式,但它有效。欢迎提出建议。

答案 1 :(得分:0)

首先,您有一个拼写错误,将'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

答案 2 :(得分:0)

如果您对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}

Reult on second dataset:

ids     ct  combination
{1,2}   2   {background.png,2,barB.png}
{1}     1   {background.png,1,fooA.png}