编辑:
正如pozs所指出的那样,typeof
函数有两个版本:一个用于JSON,一个用于SQL。这是你要找的查询:
SELECT
json_data.key,
jsonb_typeof(json_data.value),
count(*)
FROM x, jsonb_each(x.data) AS json_data
group by key, jsonb_typeof
order by key, jsonb_typeof;
旧回答:(嘿,它起作用了...)
此查询将返回密钥的类型:
SELECT
json_data.key,
pg_typeof(json_data.value),
json_data.value
FROM x, jsonb_each(x.data) AS json_data;
很遗憾,您会发现Postgres不区分不同的JSON类型。它将所有内容视为jsonb
,因此结果如下:
key1 | value1 | value
------+--------+-----------
a | jsonb | "test"
b | jsonb | 123
c | jsonb | null
d | jsonb | true
a | jsonb | "test"
b | jsonb | 123
c | jsonb | null
d | jsonb | "yay"
e | jsonb | "foo"
f | jsonb | [1, 2, 3]
(10 rows)
然而,
JSON基本类型并不多,输出结果似乎是清晰明了的。因此,以下查询会达到您的目的:
with jsontypes as (
SELECT
json_data.key AS key1,
CASE WHEN left(json_data.value::text,1) = '"' THEN 'String'
WHEN json_data.value::text ~ '^-?\d' THEN
CASE WHEN json_data.value::text ~ '\.' THEN 'Number'
ELSE 'Integer'
END
WHEN left(json_data.value::text,1) = '[' THEN 'Array'
WHEN left(json_data.value::text,1) = '{' THEN 'Object'
WHEN json_data.value::text in ('true', 'false') THEN 'Boolean'
WHEN json_data.value::text = 'null' THEN 'Null'
ELSE 'Beats Me'
END as jsontype
FROM x, jsonb_each(x.data) AS json_data
)
select *, count(*) from jsontypes
group by key1, jsontype
order by key1, jsontype;
输出:
key1 | jsontype | count
------+----------+
a | String | 2
b | Integer | 2
c | Null | 2
d | Boolean | 1
d | String | 1
e | String | 1
f | Array | 1
(7 rows)
INSERT
语句格式不太对。 - Travisjson[b]_typeof(json[b])
函数可以准确地提供您所需的内容(需要 PostreSQL 9.4+)。但我不确定您想要如何汇总结果,例如,您想如何表示d | boolean:1 string:1
行? - pozstypeof
函数,我就没有想过去寻找第二个。 - Travisjsonb_typeof
比以前快了约10%,感谢大家。 - Kokizzu