Postgres - 使用嵌套数组和数组内的对象查询 json
Postgres - query json with nested arrray and objects inside array
我将数据存储在 Postgres 12 table 中作为 jsonb,jsonb 的结构在数组中有一个数组。
如何从嵌套数组中获取值?我可以从一级数组中获取值,但不能从二级数组中获取值。
这是 json
的简化示例
{
"id": 1,
"external_order_id": {
"id": "2"
},
"customer": {
"external_customer_id": {
"id": "3"
}
},
"line_items": [
{
"sku": "SKU-1",
"properties": [
{
"name": "colour",
"value": "red"
},
{
"name": "size",
"value": "large"
}
],
"external_product_id": {
"id": "4"
},
"external_variant_id": {
"id": "5"
}
},
{
"sku": "SKU-2",
"properties": [
{
"name": "colour",
"value": "black"
},
{
"name": "size",
"value": "small"
}
],
"external_product_id": {
"id": "8"
},
"external_variant_id": {
"id": "9"
}
}
]
}
使用 jsonb_to_record 和 jsonb_to_record 设置 LATERAL 和 CROSS JOIN LATERAL,我能够从节点和第一级数组中获取值
WITH data(content) AS ( VALUES
('{
"id": 1,
"external_order_id": {
"id": "2"
},
"customer": {
"external_customer_id": {
"id": "3"
}
},
"line_items": [
{
"sku": "SKU-1",
"properties": [
{
"name": "colour",
"value": "red"
},
{
"name": "size",
"value": "large"
}
],
"external_product_id": {
"id": "4"
},
"external_variant_id": {
"id": "5"
}
},
{
"sku": "SKU-2",
"properties": [
{
"name": "colour",
"value": "black"
},
{
"name": "size",
"value": "small"
}
],
"external_product_id": {
"id": "8"
},
"external_variant_id": {
"id": "9"
}
}
]
}'::jsonb)
)
select ord.*
,ext.id as external_order_id
,cus.id as external_customer_id
,line_items.*
FROM data,
jsonb_to_record(content) as ord(id int),
LATERAL jsonb_to_record(content->'external_order_id') as ext(id text),
LATERAL jsonb_to_record(content#>'{customer, external_customer_id}') as cus(id text)
CROSS JOIN LATERAL jsonb_to_recordset(content->'line_items') line_items(sku text)
这是目前的结果
| id | external_order_id | external_customer_id | sku |
|----|-------------------|----------------------|-------|
| 1 | 2 | 3 | SKU-1 |
| 1 | 2 | 3 | SKU-2 |
我想要实现的是。
理想情况下,这将在不知道 属性 names
的值的情况下实现
| id | external_order_id | external_customer_id | sku | external_product_id | external_variant_id | property_name | property_value |
|----|-------------------|----------------------|-------|---------------------|---------------------|---------------|----------------|
| 1 | 2 | 3 | SKU-1 | 4 | 5 | colour | red |
| 1 | 2 | 3 | SKU-1 | 4 | 5 | size | large |
| 1 | 2 | 3 | SKU-2 | 8 | 9 | colour | black |
| 1 | 2 | 3 | SKU-2 | 8 | 9 | size | small |
WITH data(content) AS ( VALUES
('{
"id": 1,
"external_order_id": {
"id": "2"
},
"customer": {
"external_customer_id": {
"id": "3"
}
},
"line_items": [
{
"sku": "SKU-1",
"properties": [
{
"name": "colour",
"value": "red"
},
{
"name": "size",
"value": "large"
}
],
"external_product_id": {
"id": "4"
},
"external_variant_id": {
"id": "5"
}
},
{
"sku": "SKU-2",
"properties": [
{
"name": "colour",
"value": "black"
},
{
"name": "size",
"value": "small"
}
],
"external_product_id": {
"id": "8"
},
"external_variant_id": {
"id": "9"
}
}
]
}'::jsonb)
)
select ord.*
,ext.id as external_order_id
,cus.id as external_customer_id
,line_items.sku
,line_items.external_product_id->>'id' as external_product_id
,line_items.external_variant_id->>'id' as external_variant_id
,props.*
FROM data,
jsonb_to_record(content) as ord(id int),
LATERAL jsonb_to_record(content->'external_order_id') as ext(id text),
LATERAL jsonb_to_record(content#>'{customer, external_customer_id}') as cus(id text)
CROSS JOIN LATERAL jsonb_to_recordset(content->'line_items') line_items(sku text, properties jsonb, external_product_id jsonb, external_variant_id jsonb)
cross join LATERAL jsonb_to_recordset(line_items.properties) props(name text, value text)
我将数据存储在 Postgres 12 table 中作为 jsonb,jsonb 的结构在数组中有一个数组。
如何从嵌套数组中获取值?我可以从一级数组中获取值,但不能从二级数组中获取值。
这是 json
的简化示例{
"id": 1,
"external_order_id": {
"id": "2"
},
"customer": {
"external_customer_id": {
"id": "3"
}
},
"line_items": [
{
"sku": "SKU-1",
"properties": [
{
"name": "colour",
"value": "red"
},
{
"name": "size",
"value": "large"
}
],
"external_product_id": {
"id": "4"
},
"external_variant_id": {
"id": "5"
}
},
{
"sku": "SKU-2",
"properties": [
{
"name": "colour",
"value": "black"
},
{
"name": "size",
"value": "small"
}
],
"external_product_id": {
"id": "8"
},
"external_variant_id": {
"id": "9"
}
}
]
}
使用 jsonb_to_record 和 jsonb_to_record 设置 LATERAL 和 CROSS JOIN LATERAL,我能够从节点和第一级数组中获取值
WITH data(content) AS ( VALUES
('{
"id": 1,
"external_order_id": {
"id": "2"
},
"customer": {
"external_customer_id": {
"id": "3"
}
},
"line_items": [
{
"sku": "SKU-1",
"properties": [
{
"name": "colour",
"value": "red"
},
{
"name": "size",
"value": "large"
}
],
"external_product_id": {
"id": "4"
},
"external_variant_id": {
"id": "5"
}
},
{
"sku": "SKU-2",
"properties": [
{
"name": "colour",
"value": "black"
},
{
"name": "size",
"value": "small"
}
],
"external_product_id": {
"id": "8"
},
"external_variant_id": {
"id": "9"
}
}
]
}'::jsonb)
)
select ord.*
,ext.id as external_order_id
,cus.id as external_customer_id
,line_items.*
FROM data,
jsonb_to_record(content) as ord(id int),
LATERAL jsonb_to_record(content->'external_order_id') as ext(id text),
LATERAL jsonb_to_record(content#>'{customer, external_customer_id}') as cus(id text)
CROSS JOIN LATERAL jsonb_to_recordset(content->'line_items') line_items(sku text)
这是目前的结果
| id | external_order_id | external_customer_id | sku |
|----|-------------------|----------------------|-------|
| 1 | 2 | 3 | SKU-1 |
| 1 | 2 | 3 | SKU-2 |
我想要实现的是。 理想情况下,这将在不知道 属性 names
的值的情况下实现| id | external_order_id | external_customer_id | sku | external_product_id | external_variant_id | property_name | property_value |
|----|-------------------|----------------------|-------|---------------------|---------------------|---------------|----------------|
| 1 | 2 | 3 | SKU-1 | 4 | 5 | colour | red |
| 1 | 2 | 3 | SKU-1 | 4 | 5 | size | large |
| 1 | 2 | 3 | SKU-2 | 8 | 9 | colour | black |
| 1 | 2 | 3 | SKU-2 | 8 | 9 | size | small |
WITH data(content) AS ( VALUES
('{
"id": 1,
"external_order_id": {
"id": "2"
},
"customer": {
"external_customer_id": {
"id": "3"
}
},
"line_items": [
{
"sku": "SKU-1",
"properties": [
{
"name": "colour",
"value": "red"
},
{
"name": "size",
"value": "large"
}
],
"external_product_id": {
"id": "4"
},
"external_variant_id": {
"id": "5"
}
},
{
"sku": "SKU-2",
"properties": [
{
"name": "colour",
"value": "black"
},
{
"name": "size",
"value": "small"
}
],
"external_product_id": {
"id": "8"
},
"external_variant_id": {
"id": "9"
}
}
]
}'::jsonb)
)
select ord.*
,ext.id as external_order_id
,cus.id as external_customer_id
,line_items.sku
,line_items.external_product_id->>'id' as external_product_id
,line_items.external_variant_id->>'id' as external_variant_id
,props.*
FROM data,
jsonb_to_record(content) as ord(id int),
LATERAL jsonb_to_record(content->'external_order_id') as ext(id text),
LATERAL jsonb_to_record(content#>'{customer, external_customer_id}') as cus(id text)
CROSS JOIN LATERAL jsonb_to_recordset(content->'line_items') line_items(sku text, properties jsonb, external_product_id jsonb, external_variant_id jsonb)
cross join LATERAL jsonb_to_recordset(line_items.properties) props(name text, value text)