如何在postgresql中计算JSON的setof / key数?

时间:2016-03-23 07:06:02

标签: sql json postgresql

我在jsonb中有一个列存储地图,例如{'a':1,'b':2,'c':3},其中每行的键数不同。

我想算一下 - jsonb_object_keys可以检索密钥,但它在setof

有类似的东西吗?

(select count(jsonb_object_keys(obj) from XXX )

(这不会像ERROR: set-valued function called in context that cannot accept a set那样工作)

Postgres JSON Functions and Operators Document

json_object_keys(json)
jsonb_object_keys(jsonb)

setof text  Returns set of keys in the outermost JSON object.
json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}')  

json_object_keys
------------------
f1
f2

交叉表是不可行的,因为密钥的数量可能很大。

4 个答案:

答案 0 :(得分:7)

您可以将密钥转换为数组并使用array_length来获取:

select array_length(array_agg(A.key), 1) from (
    select json_object_keys('{"f1":"abc","f2":{"f3":"a", "f4":"b"}}') as key
) A;

如果您需要为整个表格获取此内容,则可以按主键分组。

答案 1 :(得分:5)

最短:

SELECT count(*) FROM jsonb_object_keys('{"a": 1, "b": 2, "c": 3}'::jsonb);

返回3

如果你想要一张表中的所有json键,它会给出:

SELECT (SELECT COUNT(*) FROM json_object_keys(myJsonField)) nbr_keys FROM myTable;

答案 2 :(得分:4)

虽然必须使用子选择将JSON键设置转换为行,但通过跳过构建临时数组可以更快地运行以下调整的查询:

SELECT count(*) FROM
   (SELECT jsonb_object_keys('{"a": 1, "b": 2, "c": 3}'::jsonb)) v;

它有点短;)

使其成为一种功能:

CREATE OR REPLACE FUNCTION public.count_jsonb_keys(j jsonb)
  RETURNS bigint
  LANGUAGE sql
AS $function$
SELECT count(*) from (SELECT jsonb_object_keys(j)) v;
$function$

答案 3 :(得分:1)

或者,您可以在列为数组时简单地返回键的上限:

SELECT
    ARRAY_UPPER( -- Grab the upper bounds of the array
        ARRAY( -- Convert rows into an array.
            SELECT JSONB_OBJECT_KEYS(obj)
        ),
        1 -- The array's dimension we're interested in retrieving the count for
    ) AS count
FROM
    xxx

使用'{"a": 1, "b": 2, "c": 3}'::jsonb作为obj,count将导致值为3(3)。

可粘贴示例:

SELECT
    ARRAY_UPPER( -- Grab the upper bounds of the array
        ARRAY( -- Convert rows into an array.
             SELECT JSONB_OBJECT_KEYS('{"a": 1, "b": 2, "c": 3}'::jsonb)
        ),
        1 -- The array's dimension we're interested in retrieving the count for
    ) AS count