在Postgres中查询对象的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 我假设这是因为它是一个对象数组?是否可以直接寻址名称密钥 最终我需

我有一个带有json数据字段的postgres db。 我拥有的json是一个对象数组:

[{"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)