<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;
Может ли кто-нибудь помочь мне? Большое спасибо!
Проблема в том, что у вас есть два массива, которые вы хотите пройти, но только один 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';