PostgreSQL计数出现在json键/值中

时间:2016-01-08 07:48:33

标签: arrays json postgresql aggregate postgresql-9.4

给定一个文本元素数组,我想计算出现次数,并将它们作为具有文本键和整数值的子对象返回。 (PostgreSQL 9.4)

案例1 - 没有参考集

SELECT ARRAY['3G','2G','2G','3G','3G','3G','3G','4G']

应该转换为

SELECT '{"2G": 2, "3G": 5, "4G": 1}'::jsonb

案例2 - 使用参考集

给定一组可能的条目ARRAY['2G','3G','4G'],返回的json还应包含零计数的元素。

SELECT ARRAY['3G','2G','2G','3G','3G','3G','3G']

应转换为

SELECT '{"2G": 2, "3G": 5, "4G": 0}'::jsonb

我使用

在案例1和2上非常接近
-- case 1
SELECT json_object( array_agg(r.a)::text[],array_agg(r.num)::text[] ) 
FROM (
  SELECT a, count(a) as num 
  FROM unnest( ARRAY['3G','2G','2G','3G','3G','3G','3G','4G'] ) a
  GROUP BY a ORDER BY a
) r;

--case 2
SELECT json_object( array_agg(r.ref)::text[],array_agg(r.num)::text[] ) 
FROM (
  SELECT ref, count(a) as num 
  FROM unnest( ARRAY['2G','3G','4G'] ) ref
  LEFT JOIN unnest( ARRAY['3G','2G','2G','3G','3G','3G','3G'] ) a ON (ref = a)
  GROUP BY ref ORDER BY ref
) r;

但是,结果返回一个文本值,例如:

SELECT '{"2G" : "2", "3G" : "5", "4G" : "0"}'::json   -- case 2

感谢您的帮助和反馈!

1 个答案:

答案 0 :(得分:0)

对于您的情况,您可以使用聚合json_object_agg()函数,查询将更简单:

SELECT json_object_agg(r.ref,r.num) result
FROM (
  SELECT
    ref,
    count(a) AS num
  FROM unnest(ARRAY ['2G', '3G', '4G']) ref
    LEFT JOIN unnest(ARRAY ['3G', '2G', '2G', '3G', '3G', '3G', '3G']) a ON (ref = a)
  GROUP BY ref
  ORDER BY ref
) r;

结果是:

              result              
----------------------------------
 { "2G" : 2, "3G" : 5, "4G" : 0 }
(1 row)