结合来自 jsonb 数据的月份和年份 PostgreSQL 11.5

Combine month and year from jsonb data PostgreSQL 11.5

我有 PostgreSQL 11.5,其中包含类似于此 jsonb 数据的内容:

[{"name":"$.publishedMonth", "value":"04"},{"name":"$.publishedYear","value":"1972"}]
[{"name":"$.publishedMonth", "value":"07"},{"name":"$.publishedYear","value":"2020"}]

我想要的结果是:

id publishedMonthYear
1 04-1972
2 07-2020
SELECT b.field_value AS publishedMonthYear, COUNT(*)
  FROM (SELECT *
          FROM (SELECT (jsonb_array_elements(result) ::jsonb) - >> 'name' field_name,
                       (jsonb_array_elements(result) ::jsonb) - >> 'value' field_value,
                  FROM books
                 WHERE bookstore_id = '3') a
         WHERE a.field_name in ('$.publishedMonth', '$.publishedYear')) b
 GROUP BY b.field_value

提前感谢您的帮助

示例table和数据结构:dbfiddle

select id, string_agg(value - >> 'value', '-' order by value - >> 'name')
  from book b
 cross join jsonb_array_elements(b.result ::jsonb) e
 group by id
having array_agg(value - >> 'name'
 order by value - >> 'name') = '{$.publishedMonth,$.publishedYear}'

包含 table books 交叉连接到 JSONB_ARRAY_ELEMENTS()id 列的聚合而没有子查询的查询就足够了,例如

SELECT id, STRING_AGG(j ->> 'value', '-' ORDER BY j ->> 'name') AS "publishedMonthYear"
  FROM books,
       JSONB_ARRAY_ELEMENTS(result) AS arr(j)
 WHERE bookstore_id = 3
   AND j ->> 'name' IN ('$.publishedMonth','$.publishedYear')
 GROUP BY id

考虑按 j ->> 'name' 排序,这将按字母顺序提取所需的值($.publishedMonth$.publishedYear)。

Demo

如果需要计算串联的“publishedMonthYear”值,则考虑使用子查询(如评论中所述)

SELECT "publishedMonthYear", COUNT(*)
  FROM
  ( SELECT STRING_AGG(j ->> 'value', '-' ORDER BY j ->> 'name') AS "publishedMonthYear"
      FROM books,
           JSONB_ARRAY_ELEMENTS(result) AS arr(j)
     WHERE bookstore_id = 3
       AND j ->> 'name' IN ('$.publishedMonth','$.publishedYear')
     GROUP BY id ) AS b
 GROUP BY "publishedMonthYear"  

Demo