How to make a efficient comma separator - sql

This is my table
create table #t(id varchar(10),value varchar(10))
insert into #t values('0001','a'),('0001','b'),('0002','c'),('0002','d')
I need a efficient method of making csv
id value
0001 a,b
0002 c,d

try this!
using Stuff with xml path('')
select id,
stuff(
(
select ',' + value from #t t1 where t1.id=t2.id for xml path(''),type).value('.','varchar(max)'),1,1,'') from #t t2
group by t2.id

Hello below given requirement both columns are in VARCHAR . So we can use SUBSTRING FUNCTION and CROSS APPLY to get Expected output
DECLARE #t TABLE (ID VARCHAR(10) ,VALUE VARCHAR(10) )
INSERT INTO #t (ID,VALUE)VALUES ('0001','a')
INSERT INTO #t (ID,VALUE)VALUES ('0001','b')
INSERT INTO #t (ID,VALUE)VALUES ('0002','c')
INSERT INTO #t (ID,VALUE)VALUES ('0002','d')
INSERT INTO #t (ID,VALUE)VALUES ('0003','e')
INSERT INTO #t (ID,VALUE)VALUES ('0003','f')
SELECT [Id],
SUBSTRING(d.Value,1, LEN(d.Value) - 1) VALUE
FROM
(
SELECT DISTINCT [Id]
FROM #t
) a
CROSS APPLY
(
SELECT Value + ', '
FROM #t AS B
WHERE A.[Id] = B.[Id]
FOR XML PATH('')
) D (Value)

Related

How to select from string array added in SQL column?

Below is my table,
create table t(
id int,
colParam varchar(max))
insert into t values(1,'["param1", "param2"]')
insert into t values(2,'["param2"]')
insert into t values(3,'["param1"]')
insert into t values(4,'["param2", "param3"]')
insert into t values(5,'["param1", "param2"]')
tried
declare #str varchar(max) = 'param1'; Select * from t where colParam like '%'+ #str+'%'
its not working for
declare #str varchar(max) = 'param1,param2'; Select * from t where colParam like '%'+ #str+'%'
i want to select rows by passing colPar as 'param1,param2' so it will result me all the records containing param1 and param2 in colParam
This quiet tricky.
create table #t(
id int,
colParam varchar(max)
)
insert into #t values(1,'["param1", "param2"]')
insert into #t values(2,'["param2"]')
insert into #t values(3,'["param1"]')
insert into #t values(4,'["param2", "param3"]')
insert into #t values(5,'["param1", "param2"]')
declare #str varchar(max) = 'param1,param2';
to Return all matching values.
select distinct id, t1.colParam from #t t1
cross apply string_split(t1.colParam, ',') t2
cross apply string_split(#str, ',') t3
where t2.value like '%'+t3.value+'%'
Output:
If you are using SQL Server 2016 and above, then you can use STRING_SPLIT.
As MSDN says:
A table-valued function that splits a string into rows of substrings,
based on a specified separator character.
So your can look like this:
DECLARE #t TABLE
(
id int,
colParam varchar(max)
)
insert into #t values(1,'["param1", "param2"]')
insert into #t values(2,'["param2"]')
insert into #t values(3,'["param1"]')
insert into #t values(4,'["param2", "param3"]')
insert into #t values(5,'["param1", "param2"]')
SELECT
t.id
, s.col
FROM #t AS t
OUTER APPLY
(
SELECT
spl.value AS col
FROM STRING_SPLIT(
(SELECT _t.colParam FROM #t AS _t WHERE _t.id = t.id), ',') AS spl
)s

Iterating through a SQL Server 2008 R2 table variable and concatenate values

I have a table variable #Holding two columns: an id (not unique) and a message:
id message
---- -------
2 give
2 me
2 help
3 Need
3 help
1 help!
The result should be
2 give me help
3 Need help
1 help!
This it very much simplified, but shows that there are id which may exist more than once, and some kind of text which should be concatenated into a string.
I cannot manage it to loop through this table variable (but not through a table too!).
I tried a cursor (which I did not understand correctly) but it failed of course.
The number of records are not that much, not even 100 in that table variable.
Thanks yr. help
Michael
Original question
No CURSOR, WHILE loop, or User-Defined Function needed.
Just need to be creative with FOR XML and PATH.
[Note: This solution only works on SQL 2005 and later. Original question didn't specify the version in use.]
CREATE TABLE #YourTable ([ID] INT, [Name] CHAR(1), [Value] INT)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'A',4)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (1,'B',8)
INSERT INTO #YourTable ([ID],[Name],[Value]) VALUES (2,'C',9)
SELECT
[ID],
STUFF((
SELECT ', ' + [Name] + ':' + CAST([Value] AS VARCHAR(MAX))
FROM #YourTable
WHERE (ID = Results.ID)
FOR XML PATH(''),TYPE).value('(./text())[1]','VARCHAR(MAX)')
,1,2,'') AS NameValues
FROM #YourTable Results
GROUP BY ID
DROP TABLE #YourTable
This should work if you are using SQL Server.
select T1.id,
stuff((select ' '+T2.[message]
from #A as T2
where T1.id = T2.id
for xml path(''), type).value('.', 'varchar(max)'), 1, 1, '') as [message]
from #A as T1
group by T1.id
Pretty the same, just less letters in the code:
DECLARE #t AS TABLE ( id INT, msg VARCHAR(100) );
INSERT INTO #t
VALUES ( 2, 'give' );
INSERT INTO #t
VALUES ( 2, 'me' );
INSERT INTO #t
VALUES ( 2, 'help' );
INSERT INTO #t
VALUES ( 3, 'Need' );
INSERT INTO #t
VALUES ( 3, 'help' );
INSERT INTO #t
VALUES ( 1, 'help!' );
SELECT DISTINCT
id ,
(
SELECT ST1.msg + ' '
FROM #t ST1
WHERE ST1.id = ST2.id
FOR XML PATH('')
) t
FROM
#t ST2;

Extracting numbers to a table from string column between delimiters

I have a table like this
Declare #Temp Table(Data VarChar(20))
Insert Into #Temp Values('F_200_100_')
Insert Into #Temp Values('F_50_')
Insert Into #Temp Values('F_30_')
Insert Into #Temp Values('F_50_10')
Insert Into #Temp Values('F_100_')
Insert Into #Temp Values('F_20_')
I want my output to be distinct values of the numbers extracted from data column
20
30
50
100
200
I have tried using patindex but I am looking for ideas
tried this
select
Left(
SubString(Data, PatIndex('%[0-9]%', Data), 8000),
PatIndex('%[^0-9]%', SubString(Data, PatIndex('%[0-9]%', Data), 8000) + 'X')-1
)
from #temp
Reference
http://blogs.lessthandot.com/index.php/DataMgmt/DataDesign/extracting-numbers-with-sql-server
try this:
DECLARE #YourTable table (RowID int, Layout varchar(200))
INSERT INTO #YourTable
select ROW_NUMBER() over (order by (select 0)) as rn,replace(RIGHT(data,len(data)-CHARINDEX('_',data,1)),'_',',') from temptab
;WITH SplitSting AS
(
SELECT
RowID,LEFT(Layout,CHARINDEX(',',Layout)-1) AS Part
,RIGHT(Layout,LEN(Layout)-CHARINDEX(',',Layout)) AS Remainder
FROM #YourTable
WHERE Layout IS NOT NULL AND CHARINDEX(',',Layout)>0
UNION ALL
SELECT
RowID,LEFT(Remainder,CHARINDEX(',',Remainder)-1)
,RIGHT(Remainder,LEN(Remainder)-CHARINDEX(',',Remainder))
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)>0
UNION ALL
SELECT
RowID,Remainder,null
FROM SplitSting
WHERE Remainder IS NOT NULL AND CHARINDEX(',',Remainder)=0
)
SELECT distinct cast(part as int) FROM SplitSting where len(part) > 0 order by cast(part as int)

How to show multiple row values in comma separated in a single row in SQL Server 2005?

Below I have shown two tables and also the result table.
How can I get the result table in this manner as I shown on above?
select min(ID) as ID,
Val,
stuff((select ','+Cat
from Table2 as T2
where T1.Val = T2.Val
for xml path(''), type).value('.', 'nvarchar(max)'), 1, 1, '') as Cat
from Table2 as T1
group by Val
order by ID
SQL Fiddle
DECLARE #Table1 TABLE
(
id INT
,Val VARCHAR(100)
)
DECLARE #Table2 TABLE
(
id INT
,Val VARCHAR(100)
,Cat VARCHAR(100)
)
INSERT INTO #Table1
VALUES(1,'XYZ')
INSERT INTO #Table1
VALUES(2,'abc')
INSERT INTO #Table2
VALUES(1,'XYZ','a')
INSERT INTO #Table2
VALUES(1,'abc','e')
INSERT INTO #Table2
VALUES(1,'XYZ','b')
INSERT INTO #Table2
VALUES(1,'XYZ','f')
INSERT INTO #Table2
VALUES(1,'abc','g')
SELECT t1.id,t1.Val ,( SELECT STUFF((SELECT ',' + cat FROM #Table2 t2 WHERE t2.Val = t1.val FOR XML PATH('')),1,1,''))
FROM #Table1 t1
You can define a CLR user-defined aggregate to do it. I posted a detailed description of such a solution as an answer to another question - TSQL Comma Separation. There you'll also find a link to a blog post that discusses the problems you may encounter while developing a CLR aggregate.
After you deploy the custom aggregate to the server (I named the function Concat but yours may be named differently), you will be able to obtain the required result with the following query:
SELECT Val, dbo.Concat(Cat)
FROM Table2
GROUP BY Val

SQL Cross Tab Function

Hi Dear All My friends,
I want to ask one thing about sql cross tab function.Currently, I am using sql 2008 express version and my table structure is like below.
UserID Str_Value
1 A
1 B
1 C
2 A
2 B
3 D
3 E
I want to get like this .
UserID Str_Value
1 A,B,C
2 A,B
3 D,E
I don't want to use cursor.Is there any function for that one?
Please give me the right way.I really appreciate it.
Thanks.
Best Regards,
Chong
Hope this helps. You can comment ORDER BY T1.Str_Value if not needed and set the nvarchar(500) size as required
SELECT DISTINCT T1.UserId,
Stuff(
(SELECT N', ' + T2.Str_Value
FROM t T2
WHERE T2.userId = T1.userid
ORDER BY T2.Str_Value
FOR XML PATH(''),TYPE).value('text()[1]','nvarchar(500)'),1,2,N'')
AS Str_Value
FROM t T1
SELECT UserId, LEFT(Str_Value, LEN(Str_Value) - 1) AS Str_Value
FROM YourTable AS extern
CROSS APPLY
(
SELECT Str_Value + ','
FROM YourTable AS intern
WHERE extern.UserId = intern.UserId
FOR XML PATH('')
) pre_trimmed (Str_Value)
GROUP BY UserId, Str_Value
Try this:
SELECT DISTINCT
t1.UserID,
Values = SUBSTRING((SELECT ( ', ' + t2.Str_Value)
FROM dbo.Users t2
ORDER BY
t2.Str_Value
FOR XML PATH( '' )
), 3, 4000 )FROM dbo.Users t1
GROUP BY t1.UserID
create table #temp
(
userid int,
str_value varchar(1)
)
insert into #temp values (1, 'A')
insert into #temp values (1, 'B')
insert into #temp values (1, 'C')
insert into #temp values (2, 'A')
insert into #temp values (2, 'B')
insert into #temp values (3, 'D')
insert into #temp values (3, 'E')
select userid, left(x.str_value, len(x.str_value) -1) as str_value
from #temp t
cross apply
(
select str_value + ','
FROM #temp t1
where t.userid = t1.userid
for xml path('')
) x (str_value)
group by userid, x.str_value
drop table #temp