我有这样的查询-
WITH xtbl AS (SELECT xmltype ('<root>
<parent>
<item>
<item_detail>AAA</item_detail>
<item_amount>1000</item_amount>
</item>
<item>
<item_detail>BBB</item_detail>
<item_amount>2000</item_amount>
</item>
</parent>
</root>') AS xcol FROM dual)
SELECT xmlcast (
xmlquery ('root/parent/string-join[item/item_detail/text()]' PASSING xcol RETURNING CONTENT) AS VARCHAR2 (2000))
AS item_details
FROM xtbl;
尽管上面指定的示例包含一个节点,但在我的实际问题中,并非每个<parent>
节点都会包含一个<item>
节点。因此,我无法使用this答案中所述的XMLTable解决方案。
SELECT xmlcast(...
查询是我到目前为止已经尝试过的方法,它无法正常工作。我的预期输出是这个-
ITEM_DETAILS
------------------
AAA 1000, BBB 2000
请建议我如何修改XMLQuery。
答案 0 :(得分:2)
您仍然可以使用XMLTable调用:
SELECT x.*
FROM xtbl
CROSS JOIN xmltable('/root/parent/item'
PASSING xcol
COLUMNS item_detail VARCHAR2(10) path 'item_detail',
item_amount NUMBER path 'item_amount'
) x;
ITEM_DETAI ITEM_AMOUNT
---------- -----------
AAA 1000
BBB 2000
然后串联并聚合:
SELECT listagg(x.item_detail ||' '|| x.item_amount, ', ')
WITHIN GROUP (ORDER BY item_num) AS item_details
FROM xtbl
CROSS JOIN xmltable('/root/parent/item'
PASSING xcol
COLUMNS item_detail VARCHAR2(10) path 'item_detail',
item_amount NUMBER path 'item_amount',
item_num FOR ORDINALITY
) x;
ITEM_DETAILS
--------------------------------------------------
AAA 1000, BBB 2000
对于没有项目的父母,该项目只会返回null。
但是,您也可以通过XMLQuery调用来实现:
SELECT xmlquery(
'let $d :=
for $i in /root/parent/item
return concat($i/item_detail, " ", $i/item_amount)
return string-join($d, ", ")'
PASSING xcol
RETURNING CONTENT
) AS item_details
FROM xtbl;
ITEM_DETAILS
--------------------------------------------------
AAA 1000, BBB 2000
再加上一个没有项目的父项,只会返回null。
let $d :=
部分使用concat()
连接每个项目的详细信息和数量,并在它们之间留有空格。然后,使用$d
汇总所有生成的string-join()
值。
这将返回XMLType,因此要以纯字符串形式获取结果,您可以像在问题中一样使用XMLCast,或更简单地使用.getStringVal()
:
SELECT xmlquery(
...
).getStringVal() AS item_details
FROM xtbl;
答案 1 :(得分:0)
WITH xtbl AS (SELECT xmltype ('<root>
<parent>
<item>
<item_detail>AAA</item_detail>
<item_amount>1000</item_amount>
</item>
<item>
<item_detail>BBB</item_detail>
<item_amount>2000</item_amount>
</item>
</parent>
</root>') AS xcol FROM dual)
SELECT xmlcast (
xmlquery (
'string-join(/root/parent/item/string-join((*), " "), ", ")'
PASSING xcol
RETURNING CONTENT) AS VARCHAR2 (2000)
)
AS item_details
FROM xtbl;
编辑:
*没什么特别的。这是child::*
内部字符串连接:
/root/parent/item/string-join(child::*, " ")
将/root/parent/item
的每个子元素的值连接起来(这里指的是<item_detail>
和<item_amount>
。定界符是space
。
外部字符串连接将每个内部字符串连接的结果与comma
的限制器连接起来。
EDIT-2:
'string-join(/root/parent/item/string-join(
(item_detail, item_amount)
, " "
)
, ", "
)'