Преобразование значения массива json в несколько строк с использованием json_array_elements в postgres - PullRequest
2 голосов
/ 01 августа 2020

У меня есть текстовое поле с именем json_col в моей таблице postgres (версия 10). Я пытаюсь расширить два массива MyArray и impressions на несколько строк, используя SQL

select 
json_col::json -> 'content'->>'objectID' as objectID
,json_array_elements_text(json_col::json -> 'content'->'MyArray') as MyArrayValue
,json_array_elements(json_col::json -> 'content'->'impressions')->>'intent' as intent
from my_pg_table 

образцы данных

{   "content": {
    "objectID": "ABC",
    "ObjectType": "MyType",
    "MyArray": [
      "Blue",
      "Black"
    ],
    "impressions": [
      {
        "intent": "Large"
      },
      {
        "intent": "Small"
      },
      {
        "intent": "Regular"
      },
      {
        "intent": "Medium"
      }
    ]   } }

На выходе я получаю внешний массив (показы), как и ожидалось. Также первый массив (MyArray) расширяется до нескольких строк, но он не создает строку для каждой записи, созданной первым расширением массива.

Я получаю такой вывод.

  objectID  intent  MyArrayValue
   
   ABC  Large   Blue
   
   ABC  Small   Black
   
   ABC  Regular [NULL]
   
   ABC  Medium  [NULL]

Но я ищу вывод, как показано ниже.

objectID    intent  MyArrayValue

ABC Large   Blue

ABC Large   Black

ABC Small   Blue

ABC Small   Black

ABC Regular Blue

ABC Regular Black

ABC Medium  Blue

ABC Medium  Black

Пожалуйста, дайте мне знать, если у вас есть какие-либо данные.

Ответы [ 2 ]

1 голос
/ 01 августа 2020

Используйте функцию в боковых соединениях:

select 
    json_col::json -> 'content'->>'objectID' as objectID,
    impressions->>'intent' as intent,
    MyArrayValue
from my_pg_table
cross join json_array_elements(json_col::json -> 'content'->'impressions') as impressions
cross join json_array_elements_text(json_col::json -> 'content'->'MyArray') as MyArrayValue

Db <> fiddle.

1 голос
/ 01 августа 2020

Можно попробовать вот так:

with cte as (
select 
json_col::json -> 'content'->>'objectID' as objectID
,json_array_elements(json_col::json -> 'content'->'impressions')->>'intent' as intent
from my_pg_table 
),
cte1 as 
(
select 
json_col::json -> 'content'->>'objectID' as objectID
,json_array_elements_text(json_col::json -> 'content'->'MyArray') as MyArrayValue
from my_pg_table
)

select 
t1.objectID,t1.intent,t2.myarrayvalue
from cte t1 inner join cte1 t2 on t1.objectID=t2.objectID

DEMO

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...