I am having more issues with splitting stacked columns, and would love some help to complete this last part. I was trying to apply another solution I had, but with no luck.
DB Table:
ID INT,
SN varchar(100),
Types varchar(1000)
Sample:
ID SN Types
1 123 ABC,XYZ,TEST
2 234 RJK,CDF,TTT,UMB,UVX
3 345 OID,XYZ
Desired output:
ID SN Types
1 123 ABC
1 123 XYZ
1 123 TEST
....
here's a cte i have to break up a delimited string
declare @table table (ID int identity(1,1), String varchar(max))
declare @delim varchar(max)
insert into @table values ('abc,def')
insert into @table values ('ghij,klmn,opqrst')
set @delim=','
;with c as
(
select
ID,
--String,
CHARINDEX(@delim,String,1) as Pos,
case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,1,CHARINDEX(@delim,String,1)-1) else String end as value,
case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,CHARINDEX(@delim,String,1)+1,LEN(String)-CHARINDEX(@delim,String,1)) else '' end as String
from @table
union all
select
ID,
CHARINDEX(@delim,String,1) as Pos,
case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,1,CHARINDEX(@delim,String,1)-1) else String end as Value,
case when CHARINDEX(@delim,String,1)>0 then SUBSTRING(String,CHARINDEX(@delim,String,1)+1,LEN(String)-CHARINDEX(@delim,String,1)) else '' end as String
from c
where LEN(String)>0
)
select ID, Value from c
declare @T table(ID int, SN varchar(100), Types varchar(1000))
insert into @T
select 1, 123, 'ABC,XYZ,TEST' union all
select 2, 234, 'RJK,CDF,TTT,UMB,UVX' union all
select 4, 234, 'XXX' union all
select 3, 345, 'OID,XYZ'
;with cte(ID, SN, Types, Rest) as
(
select ID,
SN,
cast(substring(Types+',', 1, charindex(',', Types+',')-1) as varchar(100)),
stuff(Types, 1, charindex(',', Types), '')+','
from @T
where len(Types) > 0
union all
select ID,
SN,
cast(substring(Rest, 1, charindex(',', Rest)-1) as varchar(100)),
stuff(Rest, 1, charindex(',', Rest), '')
from cte
where len(Rest) > 0
)
select ID, SN, Types
from cte
order by ID
I use a recursive CTE to split the string. The third column Types
is populated with the first word in the Types column of @T. Stuff
will then remove the first word and populate the Rest column that then will contain everything but the first word. After UNION ALL is the recursive part that basically do the exact same thing but it uses the CTE as a source and it uses the rest
column to pick the first word. The first word of the rest
column is removed with stuff
and then ..... well it is recursive so I think I will stop here with the explanation. The recursive part will end when there are no more words left where len(Rest) > 0
.
You will need to use a cursor and a while statement as far as I can tell... Some of these indexes may be off by one, but I think this should get you there...
DECLARE MY_CURSOR Cursor
FOR
SELECT ID, SN, Types
FROM Tbl1
Open My_Cursor
DECLARE @ID int, @SN varchar(100), @types varchar(1000)
Fetch NEXT FROM MY_Cursor INTO @ID, @SN, @types
While (@@FETCH_STATUS <> -1)
BEGIN
DECLARE @Pos int
WHILE @Pos < LEN(@types)
BEGIN
DECLARE @type varchar(25)
DECLARE @nextpos int
set @nextpos = CHARINDEX(@types, ',', @pos)
SET @type = SUBSTRING(@types, @pos, @nextpos-@pos)
INSERT INTO tbl2 (ID, SN, type) VALUES (@ID, @SN, @Type)
SET @Pos = @nextpos+1
END
FETCH NEXT FROMMY_CURSOR INTO @VAR1Number, @VAR2DateTime ,@VarLongText
END
CLOSE MY_CURSOR
DEALLOCATE MY_CURSOR
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.