Dynamic Comma Seperated string into different column - sql

May someone please help me for this strange scenario. i have a data as given below.
DECLARE #TABLE TABLE
(
ID INT,
PHONE001 VARCHAR(500)
)
INSERT TEST
SELECT 1,'01323840261,01323844711' UNION ALL
SELECT 2,'' UNION ALL
SELECT 3,',01476862000' UNION ALL
SELECT 4,'01233625418,1223822583,125985' UNION ALL
SELECT 5,'2089840022,9.99021E+13'
and i am trying to put in seperate column for each comma value. the max number of column depends on the largest comma seperated string.
Expected Output
1|01323840261|01323844711|''
2|''|''|''
3|01476862000|''|''|
4|01233625418|1223822583|125985|
5|2089840022|9.99021E+13|''|

try
select id,T.c.value('t[1]','varchar(50)') as col1,
T.c.value('t[2]','varchar(50)') as col2 ,
T.c.value('t[3]','varchar(50)') as col3 from
(select id,cast ('<t>'+ replace(PHONE001,',','</t><t>') +'</t>'
as xml) x
from #TABLE) a cross apply x.nodes('.') t(c)

Related

Different behavior for select statement in SQL

I am getting two different behaviors by select statement in MS SQL
create table #alpha3 (names varchar(max))
insert into #alpha3 values ('a'), ('aa')
declare #txt varchar(max)
select top 10 #txt = concat(#txt, names, ' ') from #alpha3
select #txt;
So in the above query, the select statement is cycling through the values from the names column. And that way we can store the values in variable as a string
For the below recursive query however
with cte as
( select cast('aa' as varchar(max)) as names, 0 as num
union all
select cast (names + 'a' as varchar(max)), num+1 from cte
where num<10
)
select * from cte
In the above case however, the select statement just is taking the last value from the last row in the column and returning it to be unioned with the anchor table/statement. So it is not cycling through all the values in the column as it did in the top query.
The select statement in below query is again having the same behavior as the top query:
create table #beta (names varchar(max))
insert into #beta values ('a'), ('aa')
select * from (
select * from #beta
union all
select * from #beta) as aa
Can someone please tell why is the select statement acting differently in the recursive query?

Split a column with comma delimiter

I have a table with 3 columns with the data given below.
ID | Col1 | Col2 | Status
1 8007590006 8002240001,8002170828 I
2 8002170828 8002000004 I
3 8002000001 8002240001 I
4 8769879809 8002000001 I
5 8769879809 8002000001 I
Col2 can contain multiple comma delimited values. I need to update status to C if there is a value in col2 that is also present in col1.
For example, for ID = 1, col2 contains 8002170828 which is present in Col1, ID = 2. So, status = 'C'
From what I tried, I know it won't work where there are multiple values as I need to split that data and get individual values and then apply update.
UPDATE Table1
SET STATUS = 'C'
WHERE Col1 IN (SELECT Col2 FROM Table1)
If you are using SQL Server 2016 or later, then STRING_SPLIT comes in handy:
WITH cte AS (
SELECT ID, Col1, value AS Col2
FROM Table1
CROSS APPLY STRING_SPLIT(Col2, ',')
)
UPDATE t1
SET Status = 'C'
FROM Table1 t1
INNER JOIN cte t2
ON t1.Col1 = t2.Col2;
Demo
This answer is intended as a supplement to Tim's answer
As you don't have the native string split that came in 2016 we can make one:
CREATE FUNCTION dbo.STRING_SPLIT
(
#List NVARCHAR(MAX),
#Delimiter NVARCHAR(255)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
(
SELECT y.i.value('(./text())[1]', 'nvarchar(4000)') as value
FROM
(
SELECT x = CONVERT(XML, '<i>'
+ REPLACE(#List, #Delimiter, '</i><i>')
+ '</i>').query('.')
) AS a CROSS APPLY x.nodes('i') AS y(i)
);
GO
--credits to sqlserverperfomance.com for the majority of this code - https://sqlperformance.com/2012/07/t-sql-queries/split-strings
Now Tim's answer should work out for you, so I won't need to repeat it here
I chose an xml based approach because it performs well and your data seems sane and won't have any xml chars in it. If it ever will contain xml chars like > that will break the parsing they should be escaped then unescaped after split
If you aren't allowed to make functions you can extract everything between the RETURNS and the GO, insert it into Tim's query,tweak the variable names to be column names and it'll still work out

Find the frequency of all words from a concatenated column

I have concatenated text column derived from three columns in a table. I need to have frequency of all single words from that concatenated column.
Column1 Column2 column3
This is Test 1
This was Test two
What I need is concatenation of all three i.e. This is Test 1, This was Test two and then count of each word ie.
This - 2
is - 1
was -1
Test - 2
1- 1
two - 1
You can use string_split and cross apply to achieve the required result. try the following:
Code:
declare #tab table (col1 varchar(100), col2 varchar(100), col3 varchar(100))
insert into #tab
select 'This is', 'Test', '1'
union
select 'This was','Test','two'
select value, count(*) rec_count
from #tab
cross apply string_split((col1+' '+col2+' '+col3), ' ')
group by value

Get a specific string

It's my data and every ThroughRouteSid record has the same pattern.
six number and five comma. then I just want to get three and five
number into two record to template Table and get the same Count()
value to these two record.
For example: First record in the picture.
ThroughRouteSid(3730,2428,2428,3935,3935,3938,) Count(32).
I want a result like this:
2428 32 3935 32
I get What number I want.become two record and both have same Count value into template table
you can use XML to get your result, please refer below sample code -
create table #t1( ThroughRouteSid varchar(500) , Cnt int)
insert into #t1
select '3730,2428,2428,3935,3935,3938,' , len('3730,2428,2428,3935,3935,3938,')
union all select '1111,2222,3333,4444,5555,6666,' , len('1111,2222,3333,4444,5555,6666,')
select cast( '<xml><td>' + REPLACE( SUBSTRING(ThroughRouteSid ,1 , len(ThroughRouteSid)-1),',','</td><td>') + '</td></xml>' as xml) XmlData , Cnt
into #t2 from #t1
select XmlData.value('(xml/td)[3]' ,'int' ), Cnt ,XmlData.value('(xml/td)[5]' ,'int' ), Cnt
from #t2
First create the function referring How to Split a string by delimited char in SQL Server. Then try Querying the following
select (SELECT CONVERT(varchar,splitdata) + ' '+ Convert(varchar, [Count])+' ' FROM (select splitdata, ROW_NUMBER() over (ORDER BY (SELECT 100)) row_no
from [dbo].[fnSplitString](ThroughRouteSid,',')
where splitdata != '') as temp where row_no in (2,5)
for xml path('')) as col1 from [yourtable]
If you are using SQL Server 2016 you can do something like this:
create table #temp (ThroughRouteSid varchar(1024),[Count] int)
insert into #temp values
('3730,2428,2428,3935,3935,3938,',32),
('730,428,428,335,935,938,',28)
select
spt.value,
t.[Count]
from #temp t
cross apply (
select value from STRING_SPLIT(t.ThroughRouteSid,',') where LEN(value) > 0
)spt

select distinct elements from two columns with comma separated in sql

I have a table with two columns like this
col1 col2
a b
b a
c d
d a
I want to get distinct values of these two columns combined with comma separated.
Expected out put is like this
a,b,c,d
The following example concatenate row values into a variable
DECLARE #val nvarchar(max)
SELECT #val = COALESCE(#val + ',' + col1, col1)
FROM (SELECT col1
FROM dbo.twoColumns
UNION
SELECT col2
FROM dbo.twoColumns
) x
SELECT #val
Demo on SQLFiddle
try this , its very much easy i think
select group_concat(distinct(c)) as d
from
(
select col1 c from your_table
union
select col2 c from your_table
) as d