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 ('root/parent/string-join[item/item_detail/text()]' PASSING xcol RETURNING CONTENT) AS VARCHAR2 (2000))
           AS item_details
  FROM xtbl;

尽管上面指定的示例包含一个节点,但在我的实际问题中,并不是每个<parent>节点都包含一个<item>节点。因此,我无法使用答案中描述的 XMLTable 解决方案。

SELECT xmlcast(...查询是我迄今为止在上面尝试过的,但它不起作用。我的预期输出是这个-

ITEM_DETAILS
------------------
AAA 1000, BBB 2000

请建议我如何修改我的 XMLQuery。

4

2 回答 2

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;
于 2018-07-20T08:46:43.640 回答
1
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::*

内部字符串连接: 连接(这里它指的是and/root/parent/item/string-join(child::*, " ")的每个子元素的值。分隔符是 a 。/root/parent/item<item_detail><item_amount>space

外部字符串连接就其本身而言,将每个内部字符串连接的结果与 a 的限制器连接起来comma

编辑-2:

'string-join(/root/parent/item/string-join(
                                           (item_detail, item_amount)
                                           , " "
                                          )
             , ", "
            )' 
于 2018-07-20T12:13:25.460 回答