2014-12-03 180 views
-2

我有以下三個不同的字符串需要分成三個不同的列。將多個字符串拆分爲多個列

字符串1:

Declare @str1 varchar(max) = 'A1,A2,A3' 

字符串2:

Declare @str2 varchar(max) = 'B1,B2,B3' 

字符串3:

Declare @str2 varchar(max) = 'C1,C2,C3' 

注意我想將上面的三個字符串存儲到三個不同的列中。

期望輸出

colA colB colC 
------------------ 
A1  B1  C1 
A2  B2  C2 
A3  B3  C3 

嘗試:

SQL小提琴http://sqlfiddle.com/#!3/d41d8/41345

+1

以前問過一個巨大的數目。請嘗試搜索.... – 2014-12-03 06:34:17

+2

@MitchWheat該OP問如何拆分並將其轉換成列 – Rajesh 2014-12-03 06:53:58

+0

你的意思是這樣的:http://stackoverflow.com/questions/27250433/insert-strings-each-values-into -a-single-column – 2014-12-03 07:30:59

回答

2

我知道它有點重,但它會工作

Declare @str1 varchar(max) = 'A1,A2,A3' 
Declare @str2 varchar(max) = 'B1,B2,B3' 
Declare @str3 varchar(max) = 'C1,C2,C3' 

DECLARE @RowCount TINYINT 
DECLARE @i  TINYINT = 0 

DECLARE @Table AS TABLE 

(
colA varchar(MAX) 
,ColB varchar(MAX) 
,ColC varchar(MAX) 

) 

SET @RowCount = len(@str1) - len(replace(@str1, ',', '')) 

WHILE(@i<[email protected]) 
BEGIN 
    INSERT INTO @Table 
    SELECT LEFT(@str1,CHARINDEX(',',@str1+',',0)-1) AS colA 
      ,LEFT(@str2,CHARINDEX(',',@str2+',',0)-1) AS colB 
      ,LEFT(@str3,CHARINDEX(',',@str3+',',0)-1) AS colC 

    SET @str1 = STUFF(@str1,1,CHARINDEX(',',@str1,0),'') 
    SET @str2 = STUFF(@str2,1,CHARINDEX(',',@str2,0),'') 
    SET @str3 = STUFF(@str3,1,CHARINDEX(',',@str3,0),'') 

    SET @i = @i + 1 

END 

SELECT * FROM @Table 
0

如果你有atmost三個值那麼試試這個。

DECLARE @str1 VARCHAR(max) = 'A1,A2,A3' 

SELECT Parsename(Replace(@str1, ',', '.'), 3) 'FST_COL', 
     Parsename(Replace(@str1, ',', '.'), 2) 'SCD_COL', 
     Parsename(Replace(@str1, ',', '.'), 1) 'TRD_COL' into #temp 

或者

DECLARE @str1 VARCHAR(max) = 'A1,A2,A3', 
     @sql NVARCHAR(max), 
     @loop INT, 
     @cnt INT=1 

SELECT @loop = Len(@str1) - Len(Replace(@str1, ',', '')) + 1 

SET @sql=' WITH Split_cols (xmlcol) 
    AS (SELECT CONVERT(XML, ''<cols><col>'' 
          + Replace(''' 
     + @str1 + ''', '','', ''</col><col>'') + ''</col></cols>'') as xmlcol) 

SELECT ' 

WHILE @cnt <= @loop 
    BEGIN 
     SET @sql+=' xmlcol.value(''/cols[1]/col[' 
       + CONVERT(VARCHAR(30), @cnt) 
       + ']'', ''varchar(100)'') AS col' 
       + CONVERT(VARCHAR(30), @cnt) + ',' 
     SET @[email protected] + 1 
    END 

SET @sql=LEFT(@sql, Len(@sql) - 1) 
SET @sql +=' FROM Split_cols ' 

--PRINT @sql 

EXEC Sp_executesql @sql 
+0

我想將結果插入'#temp'表中。字符串的值是動態的。 – MAK 2014-12-03 06:37:13

+0

@MAK - 只需在末尾添加「INTO#TEMP」。 – 2014-12-03 06:39:26

+0

好的!但正如我所說的,價值觀是動態的。我將如何在這裏手動了解每個值的索引值。 – MAK 2014-12-03 06:44:38

0

這將工作用繩子和值的任何數量的不硬編碼

CREATE FUNCTION dbo.splitstring (@stringToSplit VARCHAR(MAX)) 
RETURNS 
@returnList TABLE ([ID] INT IDENTITY(1,1),[Name] [nvarchar] (500)) 
AS 
BEGIN 

DECLARE @name NVARCHAR(255) 
DECLARE @pos INT 

WHILE CHARINDEX(',', @stringToSplit) > 0 
BEGIN 
    SELECT @pos = CHARINDEX(',', @stringToSplit) 
    SELECT @name = SUBSTRING(@stringToSplit, 1, @pos-1) 

    INSERT INTO @returnList 
    SELECT @name 

    SELECT @stringToSplit = SUBSTRING(@stringToSplit, @pos+1, LEN(@stringToSplit)[email protected]) 
END 

INSERT INTO @returnList 
SELECT @stringToSplit 

RETURN 
END 






-- USE THIS PARAMETER TO PASS VALUE 
DECLARE @STRING VARCHAR(MAX)  




DECLARE @COUNT INT 
DECLARE @I INT 
DECLARE @COLUMNNAME VARCHAR(MAX) 
DECLARE @CREATETABLE VARCHAR(MAX) 
DECLARE @INSERT VARCHAR(MAX) 

IF OBJECT_ID('TEMPDB..##TEMPTABLE') IS NOT NULL 
    DROP TABLE ##TEMPTABLE 
IF OBJECT_ID('TEMPDB..##RETURNLIST') IS NOT NULL 
    DROP TABLE ##RETURNLIST 
SELECT * INTO ##RETURNLIST FROM dbo.splitstring(@STRING) 

select @COUNT = COUNT(*) from ##RETURNLIST 
SET @I=0 
SET @CREATETABLE = 'CREATE TABLE ##TEMPTABLE (' 
WHILE (@COUNT>0) 
BEGIN 
    SET @COLUMNNAME = 'COLUMN'+ CONVERT(varchar(10), @I) + ' VARCHAR(MAX)' 
    SET @CREATETABLE = @CREATETABLE + @COLUMNNAME 
    IF(@COUNT<>1) 
    SET @CREATETABLE = @CREATETABLE + ', ' 
    SET @I = @I+1 
    SET @COUNT = @COUNT -1; 
END 
SET @CREATETABLE = @CREATETABLE + ')' 

EXECUTE(@CREATETABLE) 

SET @INSERT = 'INSERT INTO ##TEMPTABLE VALUES(' 
WHILE (@I>0) 
BEGIN 

    SET @INSERT = @INSERT +''''+ (SELECT NAME FROM ##RETURNLIST WHERE ID = @COUNT+1) +'''' 
    IF(@I<>1) 
    SET @INSERT = @INSERT + ', ' 
    SET @I = @I-1 
    SET @COUNT = @COUNT +1; 
ENDenter code here 

SET @INSERT = @INSERT + ')' 

EXECUTE(@INSERT) 
EXECUTE('SELECT * FROM ##TEMPTABLE') 
0

您還沒有給出任何加入標準爲每一行的列一起加上這些值,所以我按照降序將它們加入。此解決方案可以處理列表中的任意數量的項目,但是如果數量太高,則可能需要使用MAX RECURSION查詢提示。

DECLARE @strA NVARCHAR(MAX) = 'A1,A2,A3'; 
DECLARE @strB NVARCHAR(MAX) = 'B1,B2,B3,B4'; 
DECLARE @strC NVARCHAR(MAX) = 'C1,C2,C3'; 

WITH stringData AS (
    --each group of comma separate values with a group identifier 
    SELECT 'a' AS grp, @strA AS strng 
    UNION ALL 
    SELECT 'b' AS grp, @strB 
    UNION ALL 
    SELECT 'c' AS grp, @strC 
), 
splitStrings AS (
    --a recursive CTE to split the comma separated values 
    SELECT grp, CAST('' AS NVARCHAR(MAX)) AS item, 
     strng AS cText 
    FROM stringData 

    UNION ALL 

    SELECT grp, 
     CASE 
      WHEN CHARINDEX(N',',cText,0)>0 THEN LEFT(cText,CHARINDEX(N',',cText,0)-1) --SUBSTRING(cText,0,CHARINDEX(N',',cText,0)) 
      ELSE cText 
     END, 
     RIGHT(cText,LEN(cText)-CHARINDEX(N',',cText,0)) 
    FROM splitStrings 
    WHERE cText!=item 
) 
SELECT grp, 
    item, 
    ROW_NUMBER() OVER(PARTITION BY grp ORDER BY item) AS rnum 
INTO #stringValues --put the results in a temp table so we don't need to execute the recursive CTE more than once 
FROM splitStrings 
WHERE len(item)>0; 

DECLARE @maxNum INT = (SELECT MAX(rnum) FROM #stringValues); 

--join the values together 
WITH allNums AS (
    SELECT 1 AS num 

    UNION ALL 

    SELECT num+1 
    FROM allNums 
    WHERE num<@maxNum 
) 
SELECT sa.item AS colA, 
    sb.item AS colB, 
    sc.item AS colC 
FROM allNums 
LEFT JOIN #stringValues AS sa ON sa.rnum=allNums.num AND sa.grp='A' 
LEFT JOIN #stringValues AS sb ON sb.rnum=allNums.num AND sb.grp='B' 
LEFT JOIN #stringValues AS sc ON sc.rnum=allNums.num AND sc.grp='C' 

DROP TABLE #stringValues; 
相關問題