使用分隔符将列拆分为三个单独的列

时间:2014-11-10 07:42:23

标签: mysql sql

我在表格的列中有值 例如:Abc-a,d,f,g,h; Acd-b,h,i,j; Asx-i,k,l,m

现在我想要的是我需要将值a,d,f,g,h复制到名为' Abc'的单独列中。类似于b,h,i,j到另一列" Acd"(为上述点添加清晰度,我希望所有逗号分隔值都在一个单独的列下,列名称将是字符串,它是在' - '之前加上前缀。我应该使用分隔符来分割';'

2 个答案:

答案 0 :(得分:1)

首先永远不会将数据存储为逗号分隔值,这是一种不好的做法,你应该始终规范化数据

现在,就您目前的情况而言,如果模式相同,您可以使用substring_index()函数

提取数据如下
mysql> select substring_index(substring_index('Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m',';',1),'Abc-',-1) as Abc ;
+-----------+
| Abc       |
+-----------+
| a,d,f,g,h |
+-----------+

mysql> select substring_index(substring_index('Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m',';',2),'Acd-',-1) as Acd;
+---------+
| Acd     |
+---------+
| b,h,i,j |
+---------+

mysql> select substring_index(substring_index('Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m',';',-1),'Asx-',-1) as Asx;
+---------+
| Asx     |
+---------+
| i,k,l,m |
+---------+

最后将所有内容放在一起,您可以将更新命令作为

update your_table
set
Abc = substring_index(substring_index('Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m',';',1),'Abc-',-1),
Acd = substring_index(substring_index('Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m',';',2),'Acd-',-1),
Asx = substring_index(substring_index('Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m',';',-1),'Asx-',-1) ;

请注意,我在上面的示例中添加了完整的字符串,您可以只添加存储值的列名称

答案 1 :(得分:0)

DECLARE @DATA NVARCHAR(MAX), @COLUMNROWCOUNT INT, @COLUMNVALUE NVARCHAR(MAX)
DECLARE @VALUEROWCOUNT INT, @VALUE NVARCHAR(MAX), @SQLQUERY NVARCHAR(MAX)
SET @DATA='Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m'

CREATE TABLE #TEMPCOLUMNS(
    ID int IDENTITY(1,1) NOT NULL,
    VALUE NVARCHAR(MAX)
)
CREATE TABLE #TEMPVALUES(
    ID int IDENTITY(1,1) NOT NULL,
    VALUE NVARCHAR(MAX)
)
CREATE TABLE #TEMPCOLUMNVALUE(
    ID int IDENTITY(1,1) NOT NULL,
    COLUMNNAME NVARCHAR(MAX),
    COLUMNVALUE NVARCHAR(MAX)
)

INSERT INTO #TEMPCOLUMNS
SELECT value AS VALUE
FROM dbo.Split(@DATA, ';')

SET @COLUMNROWCOUNT=1
SET @COLUMNVALUE=''
WHILE @COLUMNROWCOUNT <=(SELECT COUNT(*) FROM #TEMPCOLUMNS)
BEGIN
    SET @COLUMNVALUE=(SELECT VALUE FROM #TEMPCOLUMNS WHERE ID=@COLUMNROWCOUNT)
    TRUNCATE TABLE #TEMPVALUES

    INSERT INTO #TEMPVALUES
    SELECT value AS VALUE
    FROM dbo.Split(@COLUMNVALUE, '-')

    INSERT INTO #TEMPCOLUMNVALUE SELECT
    (SELECT VALUE FROM #TEMPVALUES WHERE ID=1) COLUMNNAME,
    (SELECT VALUE FROM #TEMPVALUES WHERE ID=2) COLUMNVALUE  

    SET @COLUMNROWCOUNT=@COLUMNROWCOUNT+1
END

SET @VALUEROWCOUNT=1
SET @VALUE=''
SET @SQLQUERY='CREATE TABLE #TEMP( '
WHILE @VALUEROWCOUNT <=(SELECT COUNT(*) FROM #TEMPCOLUMNVALUE)
BEGIN
    SET @VALUE=(SELECT COLUMNNAME FROM #TEMPCOLUMNVALUE WHERE ID=@VALUEROWCOUNT)
    SET @SQLQUERY=@SQLQUERY+@VALUE+' NVARCHAR(MAX)'
    IF (@VALUEROWCOUNT <>(SELECT COUNT(*) FROM #TEMPCOLUMNVALUE))
    BEGIN
        SET @SQLQUERY=@SQLQUERY+','
    END
    SET @VALUEROWCOUNT=@VALUEROWCOUNT+1
END
SET @SQLQUERY=@SQLQUERY+')'

SET @VALUEROWCOUNT=1
SET @VALUE=''
SET @SQLQUERY=@SQLQUERY+'INSERT INTO #TEMP SELECT '
WHILE @VALUEROWCOUNT <=(SELECT COUNT(*) FROM #TEMPCOLUMNVALUE)
BEGIN
    SET @VALUE=(SELECT COLUMNVALUE FROM #TEMPCOLUMNVALUE WHERE ID=@VALUEROWCOUNT)
    SET @SQLQUERY=@SQLQUERY+''''+@VALUE+''''
    IF (@VALUEROWCOUNT <>(SELECT COUNT(*) FROM #TEMPCOLUMNVALUE))
    BEGIN
        SET @SQLQUERY=@SQLQUERY+','
    END
    SET @VALUEROWCOUNT=@VALUEROWCOUNT+1
END
SET @SQLQUERY=@SQLQUERY+'SELECT * FROM #TEMP DROP TABLE #TEMP'

PRINT(@SQLQUERY)
EXEC(@SQLQUERY)

DROP TABLE #TEMPCOLUMNS
DROP TABLE #TEMPVALUES
DROP TABLE #TEMPCOLUMNVALUE

SQL功能:

CREATE FUNCTION [dbo].[Split]    
 (    
  @List nvarchar(2000),    
  @SplitOn nvarchar(5)    
 )      
 RETURNS @RtnValue table     
 (    

  Id int identity(1,1),    
  Value nvarchar(100)    
 )     
 AS      
 BEGIN     
  While (Charindex(@SplitOn,@List)>0)    
  Begin    

   Insert Into @RtnValue (value)    
   Select     
    Value = ltrim(rtrim(Substring(@List,1,Charindex(@SplitOn,@List)-1)))    

   Set @List = Substring(@List,Charindex(@SplitOn,@List)+len(@SplitOn),len(@List))    
  End    

  Insert Into @RtnValue (Value)    
  Select Value = ltrim(rtrim(@List))    

  Return    
 END  

请试试。