我有一个带有 json 数据字段的 postgres 数据库。我拥有的 json 是一个对象数组:
[{"name":"Mickey Mouse","age":10},{"name":"Donald Duck","age":5}]
Run Code Online (Sandbox Code Playgroud)
我正在尝试返回 JSON 数组中特定键的值,因此在上面的示例中,我想返回 name 的值。
当我使用以下查询时,我只得到一个返回的 NULL 值:
SELECT data->'name' AS name FROM json_test
Run Code Online (Sandbox Code Playgroud)
我假设这是因为它是一个对象数组?是否可以直接寻址名称键?
最终我需要做的是返回每个唯一名称的计数,这可能吗?
谢谢!
Hal*_*Ali 16
你必须UNNEST阵列JSON-对象首先使用功能(json_array_elements 或者jsonb_array_elements如果有jsonb数据类型),则可以通过指定键访问的值。
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"
Run Code Online (Sandbox Code Playgroud)
要获得唯一名称的计数,它与上面的查询类似,除了 count distinct 聚合函数应用于 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
Run Code Online (Sandbox Code Playgroud)
需要使用->>代替,->因为前者( ->>) 将提取的值转换为文本,支持相等比较(distinct count 需要),而后者( ->) 将值提取为json,不支持相等比较。
或者,转换jsonasjsonb并使用jsonb_array_elements. JSONB支持相等比较,因此可以将 COUNT DISTINCT 与提取一起使用->,即
COUNT(DISTINCT (y.x::jsonb)->'name')
Run Code Online (Sandbox Code Playgroud)
您可以使用jsonb_array_elements(使用时jsonb)或json_array_elements(使用时json)来扩展数组元素。
例如:
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;
Run Code Online (Sandbox Code Playgroud)
在这个例子中,sample_data_elements相当于一个表,其中有一个jsonb名为 的列elem,有两行(初始数据中的两个数组元素)。
结果由两行组成(一jsonb列,或者text如果您使用的是类型->>'name'):
extracted_name
----------------
"Mickey Mouse"
"Donald Duck"
(2 rows)
Run Code Online (Sandbox Code Playgroud)
您应该能够像往常一样对它们进行分组和聚合,以返回单个名称的计数。
小智 5
这样做:
SELECT * FROM json_test WHERE (column_name @> '[{"name": "Mickey Mouse"}]');
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
24822 次 |
| 最近记录: |