如何优化此SQL CONCAT查询以使其不具有重复信息?

时间:2015-11-25 08:35:52

标签: sql-server xml

编辑2:在后退回答后进行编辑

因此,在添加代码后,我得到以下XML,有没有办法不获取标记?否则这正是我所寻找的。

<message>
  <header>
    <command>LOCK_ORDER</command>
  </header>
  <data>
    <orders>
      <orderNr>F0123456</orderNr>
      <company>AB</company>
    </orders>
    <orderlines>
      <line>10</line>
      <line>20</line>
      <line>30</line>
      <line>40</line>
      <line>50</line>
    </orderlines>
  </data>
</message>

原帖

我有这个SQL查询,我现在选择的信息如下:

<message>
  <header>
    <command>LOCK_ORDER</command>
  </header>
  <data>
    <orderlines>
        <orderNr>FO123456</orderNr>
        <company>AB</company>
        <line>1000</line>
    </orderlines>
    <orderlines>
        <orderNr>FO123456</orderNr>
        <company>AB</company>
        <line>2000</line>
      </orderlines>
      <orderlines>
        <orderNr>FO123456</orderNr>
        <company>AB</company>
        <line>3000</line>
      </orderlines> 
  </data>
</message>

SQL查询如下所示:

DECLARE @orderNr nvarchar(40)

SET @orderNr = 'FO123456'

DECLARE @result xml = null

SET @result = (SELECT CONCAT('<message><header><command>LOCK_ORDER</command></header><data>',
            CONCAT((
                         SELECT order_num AS orderNr, line_num AS line, orderline.company 
                         FROM ORDER_LINE orderline 
                         INNER JOIN ITEM_OPTION i on orderline.ITEM_NUM = i.ITEM_NUM and orderline.WAREH_NUM = i.WAREH_NUM and orderline.COMPANY = i.COMPANY 
                         WHERE ORDER_NUM = @orderNr and i.MANAGE_STOCK = 'Y' for xml auto,elements
            )
,'</data></message>')
))

SELECT @result

但后来我意识到,永远不会有这样一个实例,即发送到此功能的信息将会有多个不同的orderNr或公司,因此多次发送它们是多余的。

我想要的是一个XML,它看起来更像是这样:

<message>
    <header>
        <command>LOCK_ORDER</command>
    </header>
    <data>
        <orderNr>FO123456</orderNr>
        <company>AB</company>
        <orderlines>
            <line>1000</line>
            <line>2000</line>
            <line>3000</line>
        </orderlines>
    </data>
</message>

我该怎么做?

2 个答案:

答案 0 :(得分:1)

使用FOR XML PATH(''), ROOT('orderlines'),如下所示:

DECLARE @orderNr nvarchar(40)

SET @orderNr = 'FO123456'

DECLARE @result xml = null

SET @result = (SELECT CONCAT('<message><header><command>LOCK_ORDER</command></header><data>',
            CONCAT((
                 CONCAT((SELECT TOP 1 order_num AS orderNr, orders.company 
                 FROM ORDER_LINE orders
                 INNER JOIN ITEM_OPTION i on orders.ITEM_NUM = i.ITEM_NUM and orders.WAREH_NUM = i.WAREH_NUM and orders.COMPANY = i.COMPANY 
                 WHERE ORDER_NUM = @orderNr and i.MANAGE_STOCK = 'Y' 
                 for xml path(''),elements)
                 ,
                (SELECT line_num AS line 
                FROM ORDER_LINE orderline 
                INNER JOIN ITEM_OPTION i on orderline.ITEM_NUM = i.ITEM_NUM and orderline.WAREH_NUM = i.WAREH_NUM and orderline.COMPANY = i.COMPANY 
                WHERE ORDER_NUM = @orderNr and i.MANAGE_STOCK = 'Y' 
                for xml PATH(''), ROOT('orderlines'))
                )
            )
,'</data></message>')
))

SELECT @result

答案 1 :(得分:1)

DECLARE @orderNr nvarchar(40)

SET @orderNr = 'FO123456'

DECLARE @result xml = null
                    SELECT @result = CONCAT('<message><header><command>LOCK_ORDER</command></header><data>',
                         (SELECT 
                           order_num         AS orderNr
                         , orderline.company AS company
                         FROM ORDER_LINE orderline 
                         INNER JOIN ITEM_OPTION i on orderline.ITEM_NUM = i.ITEM_NUM and orderline.WAREH_NUM = i.WAREH_NUM and orderline.COMPANY = i.COMPANY 
                         WHERE ORDER_NUM = @orderNr and i.MANAGE_STOCK = 'Y'
                         GROUP BY
                           order_num        
                         , orderline.company
                         for xml path('orders')
                         )
                         ,
                         (
                         SELECT line_num AS line 
                         FROM ORDER_LINE orderline 
                         INNER JOIN ITEM_OPTION i on orderline.ITEM_NUM = i.ITEM_NUM and orderline.WAREH_NUM = i.WAREH_NUM and orderline.COMPANY = i.COMPANY 
                         WHERE ORDER_NUM = @orderNr and i.MANAGE_STOCK = 'Y'

                         for xml path(''),ROOT ('orderlines')
                         ),'</data></message>'
                         )

SELECT @result