微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

将具有相同 ItemNumber 的节点合并为一行

如何解决将具有相同 ItemNumber 的节点合并为一行

某些供应商定期发布带有商品价格的 XML 文件文件中有两种价格:目录价格(list Price)和折扣价格(discount Price)

<prices>
<price>
    <itemNumber>100</itemNumber>
    <currency>PLN</currency>
    <amount>2.98</amount>
    <type>listPrice</type>
</price>
<price>
    <itemNumber>100</itemNumber>
    <currency>PLN</currency>
    <amount>1.19</amount>
    <type>discountPrice</type>
</price>
<price>
    <itemNumber>101</itemNumber>
    <currency>PLN</currency>
    <amount>3.88</amount>
    <type>listPrice</type>
</price>
<price>
    <itemNumber>101</itemNumber>
    <currency>PLN</currency>
    <amount>2.76</amount>
    <type>discountPrice</type>
</price>
<price>
    <itemNumber>102</itemNumber>
    <currency>PLN</currency>
    <amount>4.55</amount>
    <type>listPrice</type>
</price>
<price>
    <itemNumber>102</itemNumber>
    <currency>PLN</currency>
    <amount>3.20</amount>
    <type>discountPrice</type>
</price>
<price>
    <itemNumber>103</itemNumber>
    <currency>PLN</currency>
    <amount>3.38</amount>
    <type>listPrice</type>
</price>
<price>
    <itemNumber>103</itemNumber>
    <currency>PLN</currency>
    <amount>2.90</amount>
    <type>discountPrice</type>
</price>
<price>
    <itemNumber>104</itemNumber>
    <currency>PLN</currency>
    <amount>2.98</amount>
    <type>listPrice</type>
</price>
<price>
    <itemNumber>104</itemNumber>
    <currency>PLN</currency>
    <amount>1.19</amount>
    <type>discountPrice</type>
</price>
</prices>

目前我正在将 XML 文件上传数据库,然后我正在使用从 xml 表中获取的数据创建 tmp 表。

SELECT
@supplierID     AS supplierID,a.product.query('itemNumber').value('.','varchar(50)')   AS supplierCode,a.product.query('amount').value('.','MONEY') AS PricePLN,a.product.query('type').value('.','varchar(50)') AS NetPriceTypePLN,GETDATE()         AS CreateDate
INTO Prices_tmp
FROM ImportedXML x(nolock)
OUTER APPLY x.xmlData.nodes('prices/price') as a(product)
where 
x.Fileid = 111

我正在努力解决的问题是如何读取 XML 以在一行中获取两个价格 喜欢:

ItemNumber | ListedPriceAmount | discountPriceAmount
100        | 2.98              | 1.19
101        | 3.88              | 2.76
102        | 4.55              | 3.20
103        | 3.38              | 2.90

你能帮我吗?我花了很多时间自己尝试。

解决方法

请尝试以下解决方案。

要点:

  • 将适当的 XML 分解为关系/矩形格式。
  • 简单模拟 PIVOT 操作以实现所需 输出。

SQL

DECLARE @xml XML = 
N'<prices>
    <price>
        <itemNumber>100</itemNumber>
        <currency>PLN</currency>
        <amount>2.98</amount>
        <type>listPrice</type>
    </price>
    <price>
        <itemNumber>100</itemNumber>
        <currency>PLN</currency>
        <amount>1.19</amount>
        <type>discountPrice</type>
    </price>
    <price>
        <itemNumber>101</itemNumber>
        <currency>PLN</currency>
        <amount>3.88</amount>
        <type>listPrice</type>
    </price>
    <price>
        <itemNumber>101</itemNumber>
        <currency>PLN</currency>
        <amount>2.76</amount>
        <type>discountPrice</type>
    </price>
    <price>
        <itemNumber>102</itemNumber>
        <currency>PLN</currency>
        <amount>4.55</amount>
        <type>listPrice</type>
    </price>
    <price>
        <itemNumber>102</itemNumber>
        <currency>PLN</currency>
        <amount>3.20</amount>
        <type>discountPrice</type>
    </price>
    <price>
        <itemNumber>103</itemNumber>
        <currency>PLN</currency>
        <amount>3.38</amount>
        <type>listPrice</type>
    </price>
    <price>
        <itemNumber>103</itemNumber>
        <currency>PLN</currency>
        <amount>2.90</amount>
        <type>discountPrice</type>
    </price>
    <price>
        <itemNumber>104</itemNumber>
        <currency>PLN</currency>
        <amount>2.98</amount>
        <type>listPrice</type>
    </price>
    <price>
        <itemNumber>104</itemNumber>
        <currency>PLN</currency>
        <amount>1.19</amount>
        <type>discountPrice</type>
    </price>
</prices>';

WITH rs AS
(
    SELECT c.value('(itemNumber/text())[1]','varchar(50)') AS ItemNumber,c.value('(amount/text())[1]','money') AS amount,c.value('(type/text())[1]','varchar(50)') AS type 
    FROM @xml.nodes('/prices/price') AS t(c)
)
-- simulates PIVOT operation
SELECT DISTINCT
    ItemNumber,MAX(IIF(type = 'listPrice',amount,0)) OVER (PARTITION BY ItemNumber) AS ListedPriceAmount,MAX(IIF(type = 'discountPrice',0)) OVER (PARTITION BY ItemNumber) AS discountPriceAmount
FROM rs;

输出

+------------+-------------------+---------------------+
| ItemNumber | ListedPriceAmount | discountPriceAmount |
+------------+-------------------+---------------------+
|        100 |              2.98 |                1.19 |
|        101 |              3.88 |                2.76 |
|        102 |              4.55 |                3.20 |
|        103 |              3.38 |                2.90 |
|        104 |              2.98 |                1.19 |
+------------+-------------------+---------------------+
,

如果pivot操作太难记了,试试这个方法:

DECLARE @xml XML = '...'

WITH rs AS
(
    SELECT c.value('(itemNumber/text())[1]','varchar(50)') AS type 
    FROM @xml.nodes('/prices/price') AS t(c)
),sr as
(
    SELECT
            ItemNumber,amount ListedPriceAmount,0 discountPriceAmount 
    FROM rs
    where type = 'listPrice'
    union
    SELECT
            ItemNumber,0 ListedPriceAmount,amount discountPriceAmount 
    FROM rs
    where type = 'discountPrice'
)
select ItemNumber,sum(ListedPriceAmount) ListedPriceAmount,sum(discountPriceAmount) discountPriceAmount
from sr
group by ItemNumber

结果与 Yitzhak 的回答相同。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?