Анализ Snowflake XML: извлечение атрибута значения тега в Snowflake sql

  <ROOM name = "Closet">
    <ITEMS>
      <ITEM ageM = "6" brand = "Ross'" costToReplace = "25" desc = "Sweater shawl" id = "11" lineNum = "11" method = "2" purchasedFrom = "Ross'" qtyLost = "1" use = "1">
        <IMAGES></IMAGES>
        <ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
      </ITEM>
      <ITEM ageY = "2" brand = "GAP" costToReplace = "20" desc = "white long sleeve shirt" id = "12" lineNum = "12" method = "2" purchasedFrom = "GAP" qtyLost = "1">
        <IMAGES></IMAGES>
        <ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
      </ITEM>
    </ITEMS>
  </ROOM>
  <ROOM name = "Kitchen">
    <ITEMS>
      <ITEM ageM = "6" ageY = "1" brand = "Pier 1 Imports" costToReplace = "30" desc = "Wine decanter" id = "13" lineNum = "13" method = "3" purchasedFrom = "Pier 1 Imports" qtyLost = "1" use = "1">
        <IMAGES></IMAGES>
        <ITEM_RECEIPT_INFOS></ITEM_RECEIPT_INFOS>
      </ITEM>
    </ITEMS>
  </ROOM>
</ROOMS>

Возвращаемые значения идентификатора предполагают 11, 12, 13, но я получил только 11, 12.

Мой код:

Имя столбца — комната, Имя таблицы — item_xml.

select 
  rs.value:"@id" ::string
from item_xml,  LATERAL FLATTEN( INPUT => XMLGET(XMLGET(item_xml.room, 'ROOM'),'ITEMS'):"$") rs;

Может ли кто-нибудь помочь мне? Большое спасибо!

ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
1
0
24
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Проблема в том, что у вас есть два массива, которые вы хотите пройти, но только один FLATTEN,

таким образом, вам нужен еще один FLATEN, но хитрость здесь в том, что «Кухня» имеет только один элемент в ITEMS, который в большинстве XML-анализов неправильно сопоставляется с объектом (иначе это происходит и в снежинке).

Таким образом, вы должны преобразовать вывод «элементов» из «Комнаты» в массив, прежде чем использовать его:

select
    i.value:"@id" ::string
from item_xml
    ,LATERAL FLATTEN( INPUT => room:"$") as r
    ,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;

дает:

I.VALUE:"@ID" ::STRING
11
12
13

технически вы действительно должны обернуть все массивы, поэтому, когда данные представляют собой один элемент, ваш SQL не взрывается. таким образом, ваше решение должно быть:

select
    i.value:"@id" ::string
from item_xml
    ,LATERAL FLATTEN( INPUT => to_array(room:"$")) as r
    ,LATERAL FLATTEN( INPUT => to_array(XMLGET(r.value,'ITEMS'):"$") ) i
;

Большое спасибо за ваше решение, оно работает. Я также придумал другой способ сделать это, select GET(div.value, '@id')::integer as itemid from item_xml, LATERAL FLATTEN(INPUT=>get(room,'$'), recursive=>true) div where get(div.value, '@') = 'ITEM';

Cheryl 18.03.2022 20:19

Очень красивое решение.

Simeon Pilgrim 18.03.2022 21:40

Другие вопросы по теме