need help on a query using substring
-
Friday, January 25, 2013 9:27 PM
Hi I have a scenario like
I/P
Body Type Name
123-4567-89 1 xyz
12-3-45-89 2 abc
O/P
Body Type Name
123 1 xyz
4567 1 xyz
89 1 xyz
12 2 abc
3 2 abc
45 2 abc
89 2 abc
Can you please help on this??
Thanks
Raaz
- Edited by raaz123 Friday, January 25, 2013 9:31 PM
All Replies
-
Friday, January 25, 2013 9:37 PM
Try -
--Split function - Create the function CREATE FUNCTION [dbo].[ufn_SplitIntArray] ( @List VARCHAR(max), @Delimiter CHAR(1) ) RETURNS @Items TABLE (Item VARCHAR(10)) AS BEGIN DECLARE @Item VARCHAR(12), @Pos INT WHILE len(@List) > 0 BEGIN SET @Pos = charindex(@Delimiter, @List) IF @Pos = 0 SET @Pos = len(@List) + 1 SET @Item = left(@List, @Pos - 1) INSERT @Items SELECT ltrim(rtrim(@Item)) --SELECT convert(INT, ltrim(rtrim(@Item))) SET @List = substring(@List, @Pos + len(@Delimiter), len(@List)) END RETURN END GO --Example using the above created function DECLARE @t TABLE(Body VARCHAR(15),TypeName VARCHAR(15)) INSERT INTO @t(Body,TypeName) VALUES('123-4567-89','1xyz'),('12-3-45-89','2abc') SELECT cply.Item,TypeName FROM @t CROSS APPLY dbo.ufn_SplitIntArray(Body,'-') AS cplyNarsimha
-
Friday, January 25, 2013 9:39 PM
That is an awfully weird requirement. And to match, this is an awfully weird query. The ROW_NUMBER function did not behave at all as I expected. But, it works, I guess.
Declare @tvTable Table ( BodyType varchar(20) ,BodyName varchar(20) ) Insert @tvTable Values ('123-4567-89 1', 'xyz') ,('12-3-45-89 2', 'abc') ;with cte as ( Select split.Item BodyTypePartThing ,t.BodyType ,ROW_NUMBER() OVER(Partition By t.BodyType Order By t.BodyType) RowNumber From @tvTable t Cross Apply adv.fncDelimitedSplit8K(t.BodyType, ' ') split ) Select s1.Item + ' ' + c2.BodyTypePartThing As BodyType ,t.BodyName From @tvTable t join cte c on t.BodyType = c.BodyType join cte c2 on t.BodyType = c2.BodyType and c2.RowNumber = 2 Cross Apply adv.fncDelimitedSplit8K(c.BodyTypePartThing, '-') s1
Edit:
Actually, after seeing Naarasimha's response, it looks like you have three columns, not two. Makes slightly more sense, and is a lot easier. You can use any split function you find, and it will work the same. I use one from Jeff Moden:
Declare @tvTable Table ( Body varchar(20) ,BodyType int ,Name varchar(20) ) Insert @tvTable Values ('123-4567-89', 1, 'xyz') ,('12-3-45-89', 2, 'abc') Select split.Item Body ,t.BodyType ,t.[Name] From @tvTable t Cross Apply adv.fncDelimitedSplit8K(t.Body, '-') split- Edited by dgjohnson Friday, January 25, 2013 9:43 PM
-
Friday, January 25, 2013 9:42 PM
Here is a alternative to do what you asked.
declare @ip as table(body varchar(20), [type] int, name varchar(20)) insert @ip values('123-4567-89', 1, 'xyz'), ('12-3-45-89', 2, 'abc') select r.c.value('(./text())[1]', 'varchar(20)') as col1 ,[name], [type] from ( select cast('<row>' + replace(body, '-', '</row><row>') + '</row>' as xml).query('.') as xmlcol ,[type] ,name from @ip ) t cross apply t.xmlcol.nodes('/row') r(c)
- Proposed As Answer by Kalman TothMicrosoft Community Contributor, Moderator Friday, January 25, 2013 10:05 PM
- Marked As Answer by Iric WenModerator Monday, February 04, 2013 9:12 AM
-
Friday, January 25, 2013 10:30 PM
Hi Raaz,
Here is a unique function which can be used alwaysCREATE FUNCTION dbo.[SplitText](@String nvarchar(max), @Delimiter nvarchar(10))
returns @temptable TABLE (txt nvarchar(max))
WITH SCHEMABINDING
as
begin
declare @idx int
declare @slice nvarchar(max)
select @idx = LEN(@Delimiter)
if len(@String)<LEN(@Delimiter) or @String is null return
while @idx!= 0
begin
set @idx = charindex(@Delimiter,@String)
if @idx!=0
set @slice = left(@String,@idx - 1)
else
set @slice = @String
if(len(@slice)>0)
insert into @temptable(txt) values(@slice)
declare @shift int = len(@String) - @idx-LEN(@Delimiter)
if @shift<0
SET @shift=0
set @String = right(@String,@shift)
if len(@String) = 0 break
end
return
end
SELECT splitedValues.txt,BodyType,Name
FROM [SourceTable]
CROSS APPLY dbo.[SplitText](Body,'-') AS splitedValues
- Proposed As Answer by Kostya Khomyakov Friday, January 25, 2013 10:32 PM
- Marked As Answer by Iric WenModerator Monday, February 04, 2013 9:12 AM

