2016-08-20 80 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>