2017-09-05 108 views
2

可变数目我有一个这样的表SQL Server 2012中创建XML与属性

;with cte_list(ID, PROPERTY_NAME, PROPERTY_VALUE) as 
(
    select '100', 'ABC', 12 union all 
    select '100', 'AD', 32 union all 
    select '100', 'AQ', 9 union all 
    select '200', 'AES', 1 union all 
    select '200', 'FS', 5 
) 

,我想有这样的结果

ID  XML 
---  ----------------------------------- 
100, <codes ABC="12" AD="32" AQ="9"/> 
200, <codes AES="1" FS="5" /> 

这可能吗?

预先感谢您

回答

3

一种方法

;with 
cte_list(ID, PROPERTY_NAME, PROPERTY_VALUE) 
as (
select '100', 'ABC', 12 union all 
select '100', 'AD', 32 union all 
select '100', 'AQ', 9 union all 
select '200', 'AES', 1 union all 
select '200', 'FS', 5 
) 
Select A.ID 
     ,XML = cast('<codes '+Stuff((Select concat(' ',Property_Name,'="',Property_Value,'"') From cte_list Where ID=A.ID For XML Path ('')),1,1,'') + ' />' as xml) 
From (Select Distinct ID from cte_list) A 

返回

ID XML 
100 <codes ABC="12" AD="32" AQ="9" /> 
200 <codes AES="1" FS="5" /> 

注意的一点是:在property_name应该是XML安全的字符串(没有空格等)

+0

在字符串级别上创建的一个罕见时刻是一个选项:-D – Shnugo

1

具有已知属性集合的另一个选项将是PIVOT的组合和XML将省略任何NULL值的事实。

;with cte_list(ID, PROPERTY_NAME, PROPERTY_VALUE) as 
(
    select '100', 'ABC', 12 union all 
    select '100', 'AD', 32 union all 
    select '100', 'AQ', 9 union all 
    select '200', 'AES', 1 union all 
    select '200', 'FS', 5 
) 
SELECT l1.ID 
    ,(
     SELECT 
      MAX(CASE WHEN PROPERTY_NAME = 'ABC' THEN PROPERTY_VALUE END) AS [@ABC] 
      ,MAX(CASE WHEN PROPERTY_NAME = 'AD' THEN PROPERTY_VALUE END) AS [@AD] 
      ,MAX(CASE WHEN PROPERTY_NAME = 'AQ' THEN PROPERTY_VALUE END) AS [@AQ] 
      ,MAX(CASE WHEN PROPERTY_NAME = 'AES' THEN PROPERTY_VALUE END) AS [@AES] 
      ,MAX(CASE WHEN PROPERTY_NAME = 'FS' THEN PROPERTY_VALUE END) AS [@FS] 
     FOR XML PATH('code'),TYPE 
    ) AS YourCodeXML 
FROM cte_list AS l1 
GROUP BY l1.ID 

结果

ID YourCodeXML 
100 <code ABC="12" AD="32" AQ="9" /> 
200 <code AES="1" FS="5" /> 

优点:你并不需要在串级工作
的退缩:如果有一个新的属性,你就必须把它添加到名单。

另一个机会是动态创建的SQL ...