2016-08-20 73 views
1

我有这样的表:动态枢轴柱由子串

itemid     attributename value 
6829556334057807840  Part Notes Drilling Required: No,Install Time: 30 Minutes,Fascia Trimming: Yes (minor),Visibility: Exposed 

我想能够在数值列中的数据枢转到密钥值对

Example: 

    ItemId     Key     Value 
6829556334057807840  Drilling Required  No 
6829556334057807840  Install Time   30 
6829556334057807840  Fascia Trimming   Yes (minor) 

然而枢轴必须是动态因为值列可以具有多个不同的键值,具体取决于列中的内容。

+1

这实际上并不需要是动态数据透视表。您只需将分隔的字符串拆分为行,然后再分割为单独的列。 – Matt

+3

这里的* best *解决方案不是首先将这样的数据存储起来。如果可以的话,修复你的数据库,而不是试图让SQL Server进行尴尬的转换。 – DavidG

回答

2

考虑规范化你的数据库。如果您有未知数据,请使用xml(自SQL Server 2005以来受支持)或JSON(自SQL Server 2016以来受支持)。使用此查询为出发点:

WITH Src AS 
(
    SELECT * FROM (VALUES 
     ('6829556334057807840', 'Part Notes', 'Drilling Required: No,Install Time: 30 Minutes,Fascia Trimming: Yes (minor),Visibility: Exposed') 
    ) T(itemid, attributename, value) 
), Recurse AS 
(
    SELECT 
     itemid, 
     SUBSTRING(value, 1, CASE WHEN CHARINDEX(',', value, 1)=0 THEN LEN(value) ELSE CHARINDEX(',', value, 1)-1 END) Item, 
     SUBSTRING(value, CASE WHEN CHARINDEX(',', value, 1)=0 THEN LEN(value) ELSE CHARINDEX(',', value, 1)+1 END, LEN(value)) Rest 
    FROM Src 
    UNION ALL 
    SELECT 
     itemid, 
     CASE WHEN CHARINDEX(',', Rest, 1)=0 THEN Rest ELSE SUBSTRING(Rest, 1, CHARINDEX(',', Rest)-1) END Item, 
     CASE WHEN CHARINDEX(',', Rest, 1)=0 THEN NULL ELSE SUBSTRING(Rest, CHARINDEX(',', Rest)+1, LEN(Rest)) END Rest 
    FROM Recurse 
    WHERE Rest IS NOT NULL 
) 
SELECT 
    itemid, 
    SUBSTRING(Item, 1, CHARINDEX(':', Item)-1) [Key], 
    SUBSTRING(Item, CHARINDEX(':', Item)+1, LEN(Item)) [Value] 
FROM Recurse 

它返回:与XML

itemid    Key     Value 
------------------- -------------------- ------------- 
6829556334057807840 Drilling Required  No 
6829556334057807840 Install Time   30 Minutes 
6829556334057807840 Fascia Trimming  Yes (minor) 
6829556334057807840 Visibility   Exposed 
0

另一种方式:

DECLARE @xml xml 

SELECT @xml = (
    SELECT CAST('<item id="' + CAST(itemid as nvarchar(100)) +'"><row><key>' + 
      REPLACE(REPLACE([value],',','</value></row><row><key>'),': ','</key><value>')+'</value></row></item>' as xml) 
    FROM YourTable 
    FOR XML PATH('') 
) 

SELECT t.v.value('../@id','bigint') ItemId,          
     t.v.value('key[1]','nvarchar(max)') [Key], 
     t.v.value('value[1]','nvarchar(max)') [Value] 
FROM @xml.nodes('/item/row') as t(v) 

为您提供表的样本,输出将是:

ItemId    Key     Value 
6829556334057807840 Drilling Required No 
6829556334057807840 Install Time  30 Minutes 
6829556334057807840 Fascia Trimming  Yes (minor) 
6829556334057807840 Visibility   Exposed 

这是您获得的XML数据将表格转换为XML PATH并进行替换后:

<item id="6829556334057807840"> 
    <row> 
    <key>Drilling Required</key> 
    <value>No</value> 
    </row> 
    <row> 
    <key>Install Time</key> 
    <value>30 Minutes</value> 
    </row> 
    <row> 
    <key>Fascia Trimming</key> 
    <value>Yes (minor)</value> 
    </row> 
    <row> 
    <key>Visibility</key> 
    <value>Exposed</value> 
    </row> 
</item>