Извлечение из вложенного JSON в SQL

У меня есть столбец json в таблице вместе с идентификатором:

идентификатор json_col abc123 json_text

Значение json показано ниже:

[
  {
    "type": 0,
    "isPro": true,
    "addOns": [
      {
        "cod": "DAIRY_PLAN",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 140,
        "goodsType": null,
        "typeAddOn": 2,
        "goodRelatedId": null
      },
      {
        "cod": "HW12-201809",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 99,
        "goodsType": null,
        "typeAddOn": 1,
        "goodRelatedId": null
      },
      {
        "cod": "HW_BAND_E",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 40,
        "goodsType": null,
        "typeAddOn": 3,
        "goodRelatedId": null
      },
      {
        "cod": "HW_LEVEL_3",
        "base": 279,
        "type": 1,
        "count": 1,
        "price": 100,
        "goodsType": null,
        "typeAddOn": 4,
        "goodRelatedId": null
      }
    ]
  },
  {
    "type": 1,
    "isPro": true,
    "addOns": [
      {
        "cod": "HW12-FW",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 99.3333,
        "goodsType": null,
        "typeAddOn": 1,
        "goodRelatedId": null
      },
      {
        "cod": "HW_BAND_SHEEP_A",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 0,
        "goodsType": null,
        "typeAddOn": 3,
        "goodRelatedId": null
      },
      {
        "cod": "HW_LEVEL_2",
        "base": 99.33,
        "type": 1,
        "count": 1,
        "price": 50,
        "goodsType": null,
        "typeAddOn": 4,
        "goodRelatedId": null
      },
      {
        "cod": "SHEEP_PLAN",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 0,
        "goodsType": null,
        "typeAddOn": 2,
        "goodRelatedId": null
      }
    ]
  },
  {
    "type": 2,
    "isPro": true,
    "addOns": [
      {
        "cod": "CROP_PLAN",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 0,
        "goodsType": null,
        "typeAddOn": 2,
        "goodRelatedId": null
      },
      {
        "cod": "CW_BAND_G",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 120,
        "goodsType": null,
        "typeAddOn": 3,
        "goodRelatedId": null
      },
      {
        "cod": "HW12-CROP",
        "base": 0,
        "type": 0,
        "count": 1,
        "price": 99,
        "goodsType": null,
        "typeAddOn": 1,
        "goodRelatedId": null
      },
      {
        "cod": "HW_LEVEL_1",
        "base": 219,
        "type": 1,
        "count": 1,
        "price": 0,
        "goodsType": null,
        "typeAddOn": 4,
        "goodRelatedId": null
      }
    ]
  }
]

Я хочу извлечь каждый вложенный объект и получить:

идентификатор item1_name item2_name item3_name item4_name item1_price item2_price item3_price item4_price abc123 json_text[0].addons[0].cod json_text[0].addons[1].cod json_text[0].addons[2].cod json_text[0].addons[3].cod json_text[0].addons[0].price json_text[0].addons[1].price json_text[0].addons[2].price json_text[0].addons[3].цена

Попробовал несколько способов получить к нему доступ, но без явного ввода номера индекса, я не смог получить все значения, используя *

например

with 
explode_array as (
select json_query(json_col,'lax $[*].addOns'  ) as array_items from get_inner_json
)


select * from explode_array

но он просто выдает ноль? но когда я проверяю документы, кажется, что это должно работать? https://trino.io/docs/current/functions/json.html#array-accessor

Есть идеи, как с этим справиться? Я использую aws athena (trino), поэтому ANSI SQL

🤔 А знаете ли вы, что...
SQL поддерживает транзакции с использованием команд BEGIN, COMMIT и ROLLBACK.


2
50
1

Ответ:

Решено

Trino не поддерживает динамическое сведение/поворот, поэтому, если вам нужны отдельные столбцы, вам придется создать их вручную. json_extract/json_extract_scalar будет работать:

select json_extract(json_col, '$[0].addOns[0].cod'),
    json_extract(json_col, '$[0].addOns[1].cod'),
    json_extract(json_col, '$[0].addOns[2].cod'),
    json_extract(json_col, '$[0].addOns[3].cod'),
    json_extract(json_col, '$[0].addOns[0].price'),
    json_extract(json_col, '$[0].addOns[1].price'),
    json_extract(json_col, '$[0].addOns[2].price'),
    json_extract(json_col, '$[0].addOns[3].price')
from dataset;

Выход:

_col0 _col1 _col2 _col3 _col4 _col5 _col6 _col7 "МОЛОЧНЫЙ_ПЛАН" "HW12-201809" "HW_BAND_E" "HW_LEVEL_3" 140 99 40 100

В противном случае вам нужно использовать массивы. Обратите внимание, что у вас есть массив в массиве, поэтому вам нужно использовать двойные подстановочные знаки:

select json_query(json_col,'lax $[*].addOns[*].cod' with array wrapper) names, -- use lax $[*].addOns[*] to get whole JSON object
    json_query(json_col,'lax $[*].addOns[*].price' with array wrapper) prices
from dataset;

Выход:

имена цены ["DAIRY_PLAN", "HW12-201809", "HW_BAND_E", "HW_LEVEL_3", "HW12-FW", "HW_BAND_SHEEP_A", "HW_LEVEL_2", "SHEEP_PLAN", "CROP_PLAN", "CW_BAND_G", "HW12-CROP" ,"HW_LEVEL_1"] [140,99,40,100,99.3333,0,50,0,0,120,99,0]