在Postgres中查询对象的JSON数组
我有一个带有json数据字段的postgres db。 我拥有的json是一个对象数组:在Postgres中查询对象的JSON数组,json,postgresql,Json,Postgresql,我有一个带有json数据字段的postgres db。 我拥有的json是一个对象数组: [{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}] 我试图返回JSON数组中特定键的值,因此在上面的示例中,我想返回name的值 当我使用以下查询时,只返回一个空值: SELECT data->'name' AS name FROM json_test 我假设这是因为它是一个对象数组?是否可以直接寻址名称密钥 最终我需
[{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}]
我试图返回JSON数组中特定键的值,因此在上面的示例中,我想返回name的值
当我使用以下查询时,只返回一个空值:
SELECT data->'name' AS name FROM json_test
我假设这是因为它是一个对象数组?是否可以直接寻址名称密钥
最终我需要做的是返回每个唯一名称的计数,这可能吗
谢谢 您必须首先使用函数(json\u array\u elements
或jsonb\u array\u elements
如果您有jsonb数据类型),取消json对象数组的测试,然后您可以通过指定键来访问值
WITH json_test (col) AS (
values (json '[{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}]')
)
SELECT
y.x->'name' "name"
FROM json_test jt,
LATERAL (SELECT json_array_elements(jt.col) x) y
-- outputs:
name
--------------
"Mickey Mouse"
"Donald Duck"
要获得唯一名称的计数,其查询类似于上述查询,除了count distinct aggregate函数应用于y.x->name
WITH json_test (col) AS (
values (json '[{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}]')
)
SELECT
COUNT( DISTINCT y.x->>'name') distinct_names
FROM json_test jt,
LATERAL (SELECT json_array_elements(jt.col) x) y
有必要使用->
而不是->
,因为前者(->
)将提取的值转换为文本,支持相等比较(不同计数需要),而后者(->
)将值提取为json,不支持相等比较
或者,将json
转换为jsonb
并使用jsonb_数组_元素
JSONB
支持相等比较,因此可以通过->
使用COUNT DISTINCT和提取,即
COUNT(DISTINCT (y.x::jsonb)->'name')
可以使用展开数组元素
例如:
WITH sample_data_array(arr) AS (
VALUES ('[{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}]'::jsonb)
)
, sample_data_elements(elem) AS (
SELECT jsonb_array_elements(arr) FROM sample_data_array
)
SELECT elem->'name' AS extracted_name FROM sample_data_elements;
在本例中,sample\u data\u elements
相当于一个表,其中有一个名为elem
的jsonb
列,有两行(初始数据中的两个数组元素)
结果由两行组成(一行为jsonb
列,如果改用->“name”
则为text
类型):
您应该能够像往常一样对它们进行分组和聚合,以返回单个名称的计数。执行以下操作:
从json_测试中选择*,其中(列_name@>“[{”name:“米老鼠”}]”);
不确定您使用的是哪个版本的PostgreSQL,但使用计数
/分组方式
对我来说很好,可以同时使用->
和->
。(使用版本10进行测试。)@Bruno,COUNT(y.x->'name')
将起作用,但是,COUNT(DISTINCT y.x->'name')
将不起作用,因为没有为json
/jsonb
类型实现相等比较器,而且,countdistinct
需要检查两个元素是否不同。我想我找到了它对我有效的原因:(a)我使用的是jsonb
(不是json
)和(b)我使用的是版本10。这是在9.4版中实现的,并添加到JSON运算符文档中:“表9.1中显示的标准比较运算符可用于jsonb,但不适用于JSON。”,因此在本例中确实存在相等运算符。@Bruno,这是一个惊人的发现!!谢谢我一直认为jsonb
不支持比较运算符,因为json
不支持比较运算符。更新相应的答案。谢谢!这正是我需要的!
extracted_name
----------------
"Mickey Mouse"
"Donald Duck"
(2 rows)