Reputation: 11
I have values in a column in the table For Eg: Abc-a,d,f,g,h;Acd-b,h,i,j;Asx-i,k,l,m
Now what i want is i need the values a,d,f,g,h to be copied into a separate column named 'Abc' similarly b,h,i,j to another column "Acd"(Adding clarity to the above point,i want all the comma separated values to come under a separate column and the column name will be the string which is prefixed before the '-').i should be splited using the delimiter ';'
Upvotes: 0
Views: 778
Reputation: 325
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 FUNCTION:
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
Please try it.
Upvotes: 0
Reputation: 44844
First of all never store data as comma separated values, its a bad practice and you should always normalize the data
Now as far as your current situation is concern and if the pattern is same you can extract data as below using the substring_index()
function
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 |
+---------+
Finally putting all together you can have the update command as
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) ;
Note that I have added the complete string in the above example, you may just add the column name where the values are stored
Upvotes: 1