2014-03-29 19 views
0

我有一個表,其中一列是具有類似如下的數據:轉換列值到一系列的行和列的SQL

column value='A,B,C,D,E,F 
XA123,Name1,10/20,1.11,27-03-2014,414BJE 
XA154,Name2,10/10,1.143,26-03-2014,414B32 
XA134,Name21,10/50,1.123,27-03-2014,414B534E 
XA125,Name32,20/20,1.1234,17-02-2014,414BJ3 
XA124,Name43,30/20,1.165,23-02-2014,414B432 
XA1256,Name324,50/60,4.31,07-01-2014,4GHH 
XA1252,Name32,70/60,6.61,09-12-2013,414B2E' 

現在我需要這個列的值一樣,在被整理出來一張單獨的桌子。 預期輸出:

A  B  C  D  E   F 
XA123 Name1 10/20 1.11 27-03-2014 414BJE 
XA154 Name2 10/10 1.143 26-03-2014 414B32 
XA134 Name21 10/50 1.123 27-03-2014 414B534E 
XA125 Name32 20/20 1.1234 17-02-2014 414BJ3 
XA124 Name43 30/20 1.165 23-02-2014 414B432 
XA1256 Name324 50/60 4.31 07-01-2014 4GHH 
XA1252 Name32 70/60 6.61 09-12-2013 414B2E 

編輯:

爲了得到上述溶液,首先,i除基於新行字符列值,並插入到一個新的表的變量:

Declare @value nvarchar(max) ='A,B,C,D,E,F 
    XA123,Name1,10/20,1.11,27-03-2014,414BJE 
    XA154,Name2,10/10,1.143,26-03-2014,414B32 
    XA134,Name21,10/50,1.123,27-03-2014,414B534E 
    XA125,Name32,20/20,1.1234,17-02-2014,414BJ3 
    XA124,Name43,30/20,1.165,23-02-2014,414B432 
    XA1256,Name324,50/60,4.31,07-01-2014,4GHH 
    XA1252,Name32,70/60,6.61,09-12-2013,414B2E' 

Declare @t Table 
(
    Id int identity(1,1), 
    Val VARCHAR(max) 
) 

while (charindex(char(13),@value)>0) 
BEGIN 
    insert into @t (Val) 
    select substring(@value,1,charindex(char(13),@value)) 

    set @value = (select substring(@value,charindex(char(13),@value)+1,len(@value))) 
END 

select * from @t 

然後,我創建了一個新的表變量和基於','的每個@t表變量的分隔值。現在希望得到一個通用和更好的解決方案。

再次編輯:

在這裏,我試圖讓一個通用的解決方案,這issue..lets說,在這些行的值可以去任何號碼,例如:

A,B,C,D,E,F could be 
A,B,C,D,E,F,G 
A,B,C,D,E,F,G,H 
A,B,C,D,E,F,G,H....Z 

所以我試圖在下面的代碼使用動態查詢來獲取解決方案,但得到一個錯誤:必須聲明標量變量「@xml」

Declare @value nvarchar(max) ='A,B,C,D,E,F,G 
    XA123,Name1,10/20,1.11,27-03-2014,414BJE,afs 
    XA154,Name2,10/10,1.143,26-03-2014,414B32,ag 
    XA134,Name21,10/50,1.123,27-03-2014,414B534E,GSF 
    XA125,Name32,20/20,1.1234,17-02-2014,414BJ3,GG 
    XA124,Name43,30/20,1.165,23-02-2014,414B432,GS 
    XA1256,Name324,50/60,4.31,07-01-2014,4GHH,GS 
    XA1252,Name32,70/60,6.61,09-12-2013,414B2E,sg' 

    declare @query varchar(max) 
    declare @xml xml 
    declare @count int 
    declare @i int = 1 

    select @xml = '<item><value>'+replace(replace(@value, ',','</value><value>'), char(10),'</value></item><item><value>')+'</value></item>' 

    DECLARE @XmlTable TABLE (XmlResult XML) 

    INSERT INTO @XmlTable select @xml 

    set @count = (SELECT XmlResult.value('count(/item/value)', 'int')/XmlResult.value('count(/item)', 'int') FROM @XmlTable) 

    SET @query = 'select ' 

    WHILE (@i <= @count) 
    BEGIN 
     IF(@i!=1) 
     BEGIN 
      set @query = @query + ', ' 
     END 
     set @query = @query + 'N.value(''substring(value['+ cast(@i as varchar) +'],1)'',''varchar(10)'')' 
     SET @i = @i + 1 

    END 
    set @query = @query + ' from ' + '@xml.nodes' + '(''item'') as T(N)' 

-- select @query 

    EXEC(@query) 

傢伙,一紐約建議...

+0

你嘗試過什麼嗎? – sakura

+0

是的,我對這個問題有解決方案......但這是實現所需輸出的非常長的方法......我正試圖找出更好的東西。 – Aryan

+2

你應該用你的方法更新這個問題。 – sakura

回答

0

試試這個,首先創建一個標量函數AS

Create FUNCTION [dbo].[funcSplit_OneVal] 
(
    @param  NVARCHAR(MAX), 
    @delimiter CHAR(1), 
    @nThVal int 
) 
RETURNS varchar(50) 

--select dbo.funcSplit_OneVal('1,2,3,4',',',5) 
AS 


BEGIN 

    Declare @t TABLE (val NVARCHAR(MAX)) 
    Declare @retVal varchar(50) = '' 

    SET @param += @delimiter 

    ;WITH a AS 
    (
     SELECT CAST(1 AS BIGINT) f, 
       CHARINDEX(@delimiter, @param) t, 
       1 seq 
     UNION ALL 
     SELECT t + 1, 
       CHARINDEX(@delimiter, @param, t + 1), 
       seq + 1 
     FROM a 
     WHERE CHARINDEX(@delimiter, @param, t + 1) > 0 
    ) 
    INSERT @t 
    SELECT SUBSTRING(@param, f, t - f)   
    FROM a 
      OPTION(MAXRECURSION 0) 
    select top (@nThVal) @retVal =val from @t  
    RETURN @retVal 
END 

然後執行以下腳本,

Declare @value nvarchar(max) ='A,B,C,D,E,F 
    XA123,Name1,10/20,1.11,27-03-2014,414BJE 
    XA154,Name2,10/10,1.143,26-03-2014,414B32 
    XA134,Name21,10/50,1.123,27-03-2014,414B534E 
    XA125,Name32,20/20,1.1234,17-02-2014,414BJ3 
    XA124,Name43,30/20,1.165,23-02-2014,414B432 
    XA1256,Name324,50/60,4.31,07-01-2014,4GHH 
    XA1252,Name32,70/60,6.61,09-12-2013,414B2E' 

DECLARE @xml AS XML = CAST(('<X>'+REPLACE(@value,' ' ,'</X><X>')+'</X>') AS XML) 
;With CTE as 
(
SELECT C.value('.', 'varchar(250)') AS value 
FROM @xml.nodes('X') as X(C) 
) 
select dbo.funcSplit_OneVal(value,',',1) 
     ,dbo.funcSplit_OneVal(value,',',2) 
     ,dbo.funcSplit_OneVal(value,',',3) 
     ,dbo.funcSplit_OneVal(value,',',4) 
     ,dbo.funcSplit_OneVal(value,',',5) 
     ,dbo.funcSplit_OneVal(value,',',6) 
    from CTE 
where len(value) > 0 

如果需要的話,那麼你可以刪除「A,B,C。 ..從變量&給最後選擇alise。

2

這...

Declare @value nvarchar(max) ='A,B,C,D,E,F 
    XA123,Name1,10/20,1.11,27-03-2014,414BJE 
    XA154,Name2,10/10,1.143,26-03-2014,414B32 
    XA134,Name21,10/50,1.123,27-03-2014,414B534E 
    XA125,Name32,20/20,1.1234,17-02-2014,414BJ3 
    XA124,Name43,30/20,1.165,23-02-2014,414B432 
    XA1256,Name324,50/60,4.31,07-01-2014,4GHH 
    XA1252,Name32,70/60,6.61,09-12-2013,414B2E' 

declare @xml xml 

select @xml = '<item><value>'+replace(replace(@value, ',','</value><value>'), char(13),'</value></item><item><value>')+'</value></item>' 

select 
N.value('substring(value[1],1)', 'varchar(10)') as V1, 
N.value('substring(value[2],1)', 'varchar(10)') as V2, 
N.value('substring(value[3],1)', 'varchar(10)') as V3, 
N.value('substring(value[4],1)', 'varchar(10)') as V4, 
N.value('substring(value[5],1)', 'varchar(10)') as V5, 
N.value('substring(value[6],1)', 'varchar(10)') as V6 
from @xml.nodes('item') as T(N) 
+0

好的答覆朋友! – AK47

+0

-1票。 2個小時前@MikaelEriksson將此標記爲重複。 1小時前,你發佈了與Mikael的答案中使用的答案相同的答案。這是錯誤的 –

+0

如果你看到我對Mikael評論的頂部的評論(謝謝你......通過解析字符串得到解決方案).....通過發佈相同的解決方案,我只是說我得到了解決方案,感謝Mikael的評論。 – Aryan