how to make comma separated values - sql

This is my table structure
create table #t(PK int,col1 varchar(10),col2 varchar(10))
insert into #t values(1,'A','a'),(2,'B','b'),(3,'C','c'),(4,'A','d'),(5,'A','e'),(6,'B','f'),(88,'F','l'),(7,'C','g'),(8,'C','h'),(9,'D','k')
output column has to look like this
col1 col2
A a,d,e
B b,f
C c,g,h
D k
F l
How'd i get such an output ?

drop table #t
create table #t(PK int,col1 varchar(10),col2 varchar(10))
insert into #t values(1,'A','a'),(2,'B','b'),(3,'C','c'),(4,'A','d'),(5,'A','e'),(6,'B','f'),(88,'F','l'),(7,'C','g'),(8,'C','h'),(9,'D','k')
select col1,SUBSTRING(d.col2,1,len(d.col2)-1)col2
from
(
select distinct col1 from #t
)a
cross apply(
select [col2]+',' from #t B where A.col1=B.col1
for xml path('')
)d (col2)
DEMO

Try this
select distinct t.[col1],
STUFF((SELECT distinct ', ' + t1.col2
from yourtable t1
where t.[col1] = t1.[col1]
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,2,'') department
from yourtable t;
Fiddle Demo

Related

How to remove non repeating character from string in SQL using fuction or SP?

I have 2 columns
1st have string like: '7,8,9,0,3'
2nd have string like: '7,8,5,6,1'
I want output like this: 9,0,3 and 5,6,1 or both combined as 9,0,3,5,6,1
Convert the below code to SP:
DECLARE #Col1 VARCHAR(100)= '7,8,9,0,3', #Col2 VARCHAR(100)= '7,8,5,6,1'
DECLARE #Table1 Table (Col1 VARCHAR(100))
DECLARE #Table2 Table (Col2 VARCHAR(100))
INSERT INTO #Table1 VALUES ( #Col1)
INSERT INTO #Table2 VALUES (#Col2)
;with tmp( Data,Col1) as (
select CONVERT(VARCHAR(100),LEFT(Col1, CHARINDEX(',',Col1+',')-1)),
STUFF(Col1, 1, CHARINDEX(',',Col1+','), '')
FROM #Table1
union all
select CONVERT(VARCHAR(100),LEFT(Col1, CHARINDEX(',',Col1+',')-1)),
STUFF(Col1, 1, CHARINDEX(',',Col1+','), '')
FROM tmp
WHERE Col1>''
)
select ID = IDENTITY(INT,1,1),CONVERT(VARCHAR(100),Data) AS Col1
INTO #T1
from tmp
;with tmp( Data,Col2) as (
select CONVERT(VARCHAR(100),LEFT(Col2, CHARINDEX(',',Col2+',')-1)),
STUFF(Col2, 1, CHARINDEX(',',Col2+','), '')
FROM #Table2
union all
select CONVERT(VARCHAR(100),LEFT(Col2, CHARINDEX(',',Col2+',')-1)),
STUFF(Col2, 1, CHARINDEX(',',Col2+','), '')
FROM tmp
WHERE Col2>''
)
select ID = IDENTITY(INT,1,1),CONVERT(VARCHAR(100),Data) AS Col2
INTO #T2
from tmp
SELECT ID = IDENTITY(INT,1,1),Col1
INTO #T3
FROM
(
SELECT Col1
FROM #T1
EXCEPT
SELECT *
FROM
(
SELECT Col1
FROM #T1
INTERSECT
SELECT Col2
FROM #T2
)T3
UNION ALL
SELECT Col2
FROM #T2
EXCEPT
SELECT *
FROM
(
SELECT Col1
FROM #T1
INTERSECT
SELECT Col2
FROM #T2
)T4
)T5
SELECT DISTINCT STUFF((SELECT ',' + Col1
FROM #T3 T1
--WHERE T1.ID=T2.Id
FOR XML PATH ('')),1,1,'')
FROM #T3 T2
DROP TABLE #T1,#T2,#T3
Demo
What you need to do is full outer join on the same table between the 2 columns.
SELECT distinct A.name1,B.name2
FROM <TABLE> A full outer join <TABLE> B on A.name1 = B.name2
where A.name1 is null or B.name2 is null

SQL SELECT Data from other table based on column value

Gurus,
I have a table like below
Id Name Source Value
1 a Dx C
2 b Rx G
3 C Tx H
I have 3 other tables like T1,T2 and T3 with structure as below. Based on "Source" column in parent table, I need to fetch "Data column" and show as result. If multiple records match need all record as comma-seperated
T1
Id Data
Dx 123
DX 011
T2
Id Data
Rx 456
Rx 022
T3
Id Data
Tx 789
I need Output as in T-SQL
Id Name Source Value Data
1 a Dx C 123,011
2 b Rx G 456 ,022
3 C Tx H 789
I tried with Case when but not successful. Need inputs
Try this:
DECLARE #t TABLE(ID INT, Name CHAR(1), Source CHAR(2), Value CHAR(1))
DECLARE #t1 TABLE(ID CHAR(2), Data NVARCHAR(20))
DECLARE #t2 TABLE(ID CHAR(2), Data NVARCHAR(20))
DECLARE #t3 TABLE(ID CHAR(2), Data NVARCHAR(20))
INSERT INTO #t VALUES
(1, 'a', 'Dx', 'C'),
(2, 'b', 'Rx', 'G'),
(3, 'c', 'Tx', 'H')
INSERT INTO #t1 VALUES('Dx', '1231')
INSERT INTO #t1 VALUES('Dx', '1232')
INSERT INTO #t1 VALUES('Dx', '1233')
INSERT INTO #t2 VALUES('Rx', '4561')
INSERT INTO #t2 VALUES('Rx', '4562')
INSERT INTO #t3 VALUES('Tx', '789')
SELECT t.ID ,
t.Name ,
t.Source ,
t.Value ,
COALESCE(c1.Data1, c2.Data2, c3.Data3) AS Data
FROM #t t
OUTER APPLY (SELECT STUFF((SELECT ',' + Data
FROM #t1 t1 WHERE t.Source = t1.ID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') AS Data1) c1
OUTER APPLY (SELECT STUFF((SELECT ',' + Data
FROM #t2 t2 WHERE t.Source = t2.ID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') AS Data2) c2
OUTER APPLY (SELECT STUFF((SELECT ',' + Data
FROM #t3 t3 WHERE t.Source = t3.ID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,1,'') AS Data3) c3
Output:
ID Name Source Value Data
1 a Dx C 1231,1232,1233
2 b Rx G 4561,4562
3 c Tx H 789
Version with CASE expression:
SELECT t.ID ,
t.Name ,
t.Source ,
t.Value ,
o.Data
FROM #t t
OUTER APPLY ( SELECT CASE t.Source
WHEN 'Dx' THEN STUFF((SELECT
',' + Data
FROM #t1 t1
WHERE t.Source = t1.ID
FOR XML PATH('') ,
TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
WHEN 'Rx' THEN STUFF((SELECT
',' + Data
FROM #t2 t2
WHERE t.Source = t2.ID
FOR XML PATH('') ,
TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
WHEN 'Tx' THEN STUFF((SELECT
',' + Data
FROM #t3 t3
WHERE t.Source = t3.ID
FOR XML PATH('') ,
TYPE
).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
END AS DATA
) o
you don't need to case, use nested ISNULLs or COALESCE and left outer joins:
Select tbl.Id, tbl.Name, tbl.Source, tbl.value,
isnull(isnull(T1.data,T2.data),T3.data) as data
from table tbl
left outer join T1 on tbl.Source = T1.Id
left outer join T2 on tbl.Source = T2.Id
left outer join T3 on tbl.Source = T3.Id

SQL Server : Select rows in rows

I have the following table in SQL Server
Names TypeID
-------------
JJ 23
KK 20
LL 15
JJ 13
KK 18
JJ 10
I want the results of my select query to appear as below
Names TypeID
---------------
JJ 23,13,10
KK 20,18
LL 15
How can i achieve this? Please help, am new to sql
This question was answered many times before. For example here: Does T-SQL have an aggregate function to concatenate strings?
A good code snippet is like this:
set nocount on;
declare #YourTable table (RowID int, HeaderValue int, ChildValue varchar(5))
insert into #YourTable VALUES (1,1,'CCC')
insert into #YourTable VALUES (2,2,'B<&>B')
insert into #YourTable VALUES (3,2,'AAA')
insert into #YourTable VALUES (4,3,'<br>')
insert into #YourTable VALUES (5,3,'A & Z')
set nocount off
SELECT
t1.HeaderValue
,STUFF(
(SELECT
', ' + t2.ChildValue
FROM #YourTable t2
WHERE t1.HeaderValue=t2.HeaderValue
ORDER BY t2.ChildValue
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,2, ''
) AS ChildValues
FROM #YourTable t1
GROUP BY t1.HeaderValue
This code is taken from the same thread to which I've posted link.
drop table #t
create table #t(names varchar(10),type1 int)
insert into #t values('JJ',23),
('KK',20),
('LL',15),
('JJ',13),
('KK',18),
('JJ',10)
select distinct names,stuff((select ',' +cast(type1 as varchar(10)) from #t t2 where t2.names=t1.names for xml path('') ),1,1,'') as TypeID
from #t t1
FIDDLE DEMO
Try this:-
SELECT Names, GROUP_CONCAT(TypeID)
FROM YOUR_TABLE
GROUP BY Names;
try this
SELECT Names, TypeID =
STUFF((SELECT ', ' + Convert(nvarchar(2),TypeID)
FROM your_table b
WHERE b.Names = a.Names
FOR XML PATH('')), 1, 2, '')
FROM your_table a
GROUP BY Names
try this code
SELECT name, GROUP_CONCAT(typeid)
FROM test
GROUP BY name

Help with TSQL join query

Based on below 2 tables
declare #t1 table
(
Id int,
Title varchar(100),
RelatedId int
)
insert into #t1 values(1,'A',2)
insert into #t1 values(1,'A',3)
declare #t2 table
(
Id int,
Title varchar(100)
)
insert into #t2 values
(2,'B'),
(3,'C')
I am trying to get the below output
Id Title RelatedItems
---------------------------------
1 A 2 (B), 3 (C)
I tried the following:
select t1.Id,t1.Title, cast(t2.Id as varchar) + ' (' + t2.Title + ')' from #t1 as t1
left outer join #t2 as t2
on t1.RelatedId=t2.Id
But that gives 2 different rows. I want just one row with the data combined in the third column (as shown above). Pls. suggest.
Use:
SELECT DISTINCT
b.id,
b.title,
STUFF((SELECT ','+ CAST(t2.id AS VARCHAR(100)) + ' ('+ t2.title +')'
FROM t2
JOIN t1 a ON a.relatedid = t2.id
WHERE a.id = b.id
FOR XML PATH('')), 1, 1, '')
FROM t1 b

Duplicates without using While or Cursor in T-SQL

ID Name
1 A
1 B
1 C
2 X
2 Y
3 P
3 Q
3 R
These are the columns in a table. I want to get output like
ID Company
1 A,B,C
2 X, Y
3 P,Q,R
Restriction is that I cannot use WHILE or CURSOR. Please write a query for the same.
This query should do it - uses FOR XML PATH which is new in SQL Server 2005 - hope you are on 2005 or higher, you didn't clearly specify.....
SELECT
ID,
STUFF(CAST((SELECT ','+Name FROM dbo.YourTable t2
WHERE t2.ID = dbo.YourTable.ID
FOR XML PATH(''), TYPE) AS VARCHAR(MAX)), 1, 1, '') AS 'Company'
FROM
dbo.YourTable
GROUP BY
ID
Here's a solution using the CROSS APPLY method:
select id, sub.names
from (
select distinct id from YourTable
) a
cross apply (
select name + ', ' as [text()]
from YourTable b
where b.id = a.id
for xml path('')
) sub(names)
For 2005 version:
CREATE TABLE dbo.TEST([Type] INTEGER, [Name] NVARCHAR(100), [Qty] INTEGER)
GO
INSERT dbo.TEST VALUES(1, N'a', 5)
INSERT dbo.TEST VALUES(1, N'b', 6)
INSERT dbo.TEST VALUES(2, N'c', 44)
INSERT dbo.TEST VALUES(3, N'd', 1)
GO
select [Type],
[Description] = replace((select [Name] + ':' + cast([Qty] as varchar) as 'data()'
from TEST where [Type] = t.[Type] for xml path('')), ' ', ',')
from dbo.TEST t
group by [Type]
go
drop table dbo.TEST
You can group on the ID to get the unique values, then get the comma separated string for each using a for xml query:
select
a.ID,
substring((
select ', ' + Name
from Test1
where Test1.ID = a.ID
for xml path('')
), 3, 1000) as Company
from
TheTable a
group by
a.ID