【问题标题】:Select dates list from xml field in SQL server从 SQL Server 的 xml 字段中选择日期列表
【发布时间】:2020-01-14 10:05:24
【问题描述】:

我正在尝试从以下 XML 中选择日期:

<output xmlns="http://www.abcde.com/pqwlv/dwh" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="46177" xsi:schemaLocation="dwhOutput.xsd">
  <parameter>
    <isCoupon>0</isCoupon>
  </parameter>
  <schedule>
    <executionDate businessDay="2020-01-09">2020-01-09</executionDate>
    <endDates>
      <item businessDay="2019-03-18">2019-03-17</item>
      <item businessDay="2019-06-17">2019-06-17</item>
      <item businessDay="2019-09-17">2019-09-17</item>
      <item businessDay="2019-12-17">2019-12-17</item>
      <item businessDay="2020-03-17">2020-03-17</item>
      <item businessDay="2020-06-17">2020-06-17</item>
    </endDates>
  </schedule>
</output>

我想从“endDates”字段中选择日期列表(“businessDay”),所以输出将是(作为表格):

endDates
----------
2019-03-18
2019-06-17
2019-09-17
2019-12-17
2020-03-17
2020-06-17

我已尝试使用此查询:

SELECT endDates.query('.') AS endDates
FROM [table]
CROSS APPLY
OUTPUT.nodes('declare namespace ns="http://www.abcde.com/pqwlv/dwh"; /ns:output/ns:schedule/ns:endDates') AS T1(endDates) 

得到:

<p1:endDates xmlns:p1="http://www.abcde.com/pqwlv/dwh">
  <p1:item businessDay="2019-03-18">2019-03-17</p1:item>
  <p1:item businessDay="2019-06-17">2019-06-17</p1:item>
  <p1:item businessDay="2019-09-17">2019-09-17</p1:item>
  <p1:item businessDay="2019-12-17">2019-12-17</p1:item>
  <p1:item businessDay="2020-03-17">2020-03-17</p1:item>
  <p1:item businessDay="2020-06-17">2020-06-17</p1:item>
</p1:endDates>

如何深入挖掘并选择日期?

【问题讨论】:

    标签: sql-server xml attributes xquery sql-server-2017


    【解决方案1】:

    离你不远了。您需要在查询开始时使用WITH XMLNAMESPACES,定义命名空间,然后您可以横向遍历FROM中的节点:

    DECLARE @xml xml = '<output xmlns="http://www.abcde.com/pqwlv/dwh" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" id="46177" xsi:schemaLocation="dwhOutput.xsd">
      <parameter>
        <isCoupon>0</isCoupon>
      </parameter>
      <schedule>
        <executionDate businessDay="2020-01-09">2020-01-09</executionDate>
        <endDates>
          <item businessDay="2019-03-18">2019-03-17</item>
          <item businessDay="2019-06-17">2019-06-17</item>
          <item businessDay="2019-09-17">2019-09-17</item>
          <item businessDay="2019-12-17">2019-12-17</item>
          <item businessDay="2020-03-17">2020-03-17</item>
          <item businessDay="2020-06-17">2020-06-17</item>
        </endDates>
      </schedule>
    </output>';
    
    WITH XMLNAMESPACES(DEFAULT 'http://www.abcde.com/pqwlv/dwh',
                       'http://www.w3.org/2001/XMLSchema-instance' AS xsi)
    SELECT eD.item.value('@businessDay','date') AS endDate
    FROM (VALUES(@XML))V(YourXML) --This would be your table
         CROSS APPLY V.YourXML.nodes('/output/schedule/endDates/item') eD(item);
    

    【讨论】:

      【解决方案2】:

      你已经接近你想要的输出了。

      SELECT  T1.endDates.value('@businessDay','DATE')
      FROM(
      SELECT @X AS COL
      )A 
      CROSS APPLY
      A.COL.nodes('declare namespace ns="http://www.abcde.com/pqwlv/dwh"; 
      /ns:output/ns:schedule/ns:endDates/ns:item') AS T1(endDates) 
      

      输出:

      (No column name)
      2019-03-18
      2019-06-17
      2019-09-17
      2019-12-17
      2020-03-17
      2020-06-17
      

      【讨论】:

        【解决方案3】:

        看来这里是最快最干净的方法。无需声明 xsi 命名空间,因为它没有被使用。

        SQL

        -- DDL and sample data population, start
        DECLARE @tbl TABLE (ID INT IDENTITY(1,1) PRIMARY KEY, xml_data XML);
        INSERT INTO @tbl
        VALUES (N'<output xmlns="http://www.abcde.com/pqwlv/dwh" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                id="46177" xsi:schemaLocation="dwhOutput.xsd">
            <parameter>
                <isCoupon>0</isCoupon>
            </parameter>
            <schedule>
                <executionDate businessDay="2020-01-09">2020-01-09</executionDate>
                <endDates>
                    <item businessDay="2019-03-18">2019-03-17</item>
                    <item businessDay="2019-06-17">2019-06-17</item>
                    <item businessDay="2019-09-17">2019-09-17</item>
                    <item businessDay="2019-12-17">2019-12-17</item>
                    <item businessDay="2020-03-17">2020-03-17</item>
                    <item businessDay="2020-06-17">2020-06-17</item>
                </endDates>
            </schedule>
        </output>');
        -- DDL and sample data population, end
        
        ;WITH XMLNAMESPACES(DEFAULT 'http://www.abcde.com/pqwlv/dwh')
        SELECT ID
            , col.value('.','DATE') AS endDates
        FROM @tbl AS tbl
            CROSS APPLY tbl.xml_data.nodes('/output/schedule/endDates/item/@businessDay') AS tab(col);
        

        输出

        +----+------------+
        | ID |  endDates  |
        +----+------------+
        |  1 | 2019-03-18 |
        |  1 | 2019-06-17 |
        |  1 | 2019-09-17 |
        |  1 | 2019-12-17 |
        |  1 | 2020-03-17 |
        |  1 | 2020-06-17 |
        +----+------------+
        

        【讨论】:

          猜你喜欢
          • 2014-11-12
          • 1970-01-01
          • 1970-01-01
          • 2013-09-08
          • 1970-01-01
          • 1970-01-01
          • 2015-05-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多