Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/70.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql 将具有相同ItemNumber的节点合并到一行中_Sql_Sql Server_Xml_Tsql_Xquery - Fatal编程技术网

Sql 将具有相同ItemNumber的节点合并到一行中

Sql 将具有相同ItemNumber的节点合并到一行中,sql,sql-server,xml,tsql,xquery,Sql,Sql Server,Xml,Tsql,Xquery,一些供应商定期发布包含商品价格的XML文件。文件中有两种类型的价格:目录价格(标价)和折扣价格(折扣价) 我正在努力解决的问题是如何读取XML以将两种价格都放在一行中 比如: 你能帮帮我吗?我花了很多时间独自尝试。请尝试以下解决方案 要提及的要点: 正确的XML分解为关系/矩形格式 枢轴操作的简单模拟,以实现所需的 输出 SQL DECLARE @xml XML = N'<prices> <price> <itemNumber>1

一些供应商定期发布包含商品价格的XML文件。文件中有两种类型的价格:目录价格(标价)和折扣价格(折扣价)

我正在努力解决的问题是如何读取XML以将两种价格都放在一行中 比如:


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

请尝试以下解决方案

要提及的要点:

  • 正确的XML分解为关系/矩形格式
  • 枢轴操作的简单模拟,以实现所需的 输出
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', amount, 0)) OVER (PARTITION BY ItemNumber) AS discountPriceAmount
FROM rs;

如果枢轴操作太难记忆,请尝试以下方法:

DECLARE @xml XML = '...'

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)
), 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的答案相同。

是XML结构。与表中数据的外观相关?示例数据和所需结果将有所帮助。项目编号=(字符串)、货币=(字符串)、价格=(整数)、价格类型=(字符串)请参见下文。您的价格是示例中的根:是整个XML还是您有多个
节点,或者可能有多个
节点?我有多个节点,但只有一个节点工作正常!谢谢你们两位,伊扎克和德扬。@Piotr别忘了向上投票,接受伊扎克的回答,并感谢你们提出的问题:)不幸的是,我的投票声望很低,但如果可以的话,我会投票的。你们俩的解决方案解决了我的问题,所以非常感谢你们!你真棒!啊,是的,我忘了那部分,所以没问题,我会把你的问题投上去:)
ItemNumber | ListedPriceAmount | discountPriceAmount
100        | 2.98              | 1.19
101        | 3.88              | 2.76
102        | 4.55              | 3.20
103        | 3.38              | 2.90
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', amount, 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 |
+------------+-------------------+---------------------+
DECLARE @xml XML = '...'

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)
), 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