Concatenate Rows in SQL with Different values [duplicate] - sql

This question already has answers here:
Concatenate column values for rows with the same values (of different columns)
(3 answers)
Closed 8 years ago.
Hello I have an issue concatinating multiple rows in different tables adding a field separator ; For example. Basically I want to concatenate all values that has the same DocumentsID and they have to have to have different fieldid. If it doesn't have fieldid just leave it blank. Hopefully that makes sense. First time asking here. Thanks again.
DocumentsID Field ID Values
1 190 Jordan
1 191 Kobe
1 192 Rose
2 191 Kobe
Expected Results
DocumentsID Values
1 Jordan; Kobe; Rose
2 Kobe

There's a same question here that you can refer.
I've modified the query used in the accepted answer just to fit in your example.
set nocount on;
declare #YourTable table (DocumentID int, FieldID int, [Values] varchar(50))
insert into #YourTable VALUES (1,190,'Jordan')
insert into #YourTable VALUES (1,191,'Kobe')
insert into #YourTable VALUES (1,192,'Rose')
insert into #YourTable VALUES (2,191,'Kobe')
set nocount off
SELECT DISTINCT
t1.DocumentID
,STUFF(
(SELECT
', ' + t2.[Values]
FROM #YourTable t2
WHERE t1.DocumentID=t2.DocumentID
ORDER BY t2.[Values]
FOR XML PATH(''), TYPE
).value('.','varchar(max)')
,1,2, ''
) AS [Values]
FROM #YourTable t1
GROUP BY t1.DocumentID,t1.[Values]

Related

How to create a query to join multiple rows from a different table into single comma delimated column in SQL Server [duplicate]

This question already has answers here:
Simulating group_concat MySQL function in Microsoft SQL Server 2005?
(12 answers)
Closed 4 years ago.
I am using SQL Server 2014, and I have two tables:
number id
------------------
36-23 1
36-23 2
id value
------------------
1 asia
2 europe
The number column is of type varchar. I want to write a query to return the following results:
number Name
---------------------------
36-23 asia,europe
I am wondering how can I do this with the help of query or functions in SQL Server.
I think using STUFF is the easiest way to go forward here.
CREATE TABLE tableID
([number] varchar(50), [id] int)
;
INSERT INTO tableID
([number], [id])
VALUES
('36-23', 1),
('36-23', 2)
;
CREATE TABLE tableLoc
([id] int, [value] varchar(50))
;
INSERT INTO tableLoc
([id], [value])
VALUES
(1, 'asia'),
(2, 'europe')
;
SELECT tableID.number, tableLoc.value INTO temp1
FROM tableID INNER JOIN tableLoc ON tableID.id = tableLoc.id;
SELECT *, STUFF((
SELECT DISTINCT ', ' + value
FROM temp1
WHERE number = t.number
FOR XML PATH('')), 1, 2, '')
FROM (
SELECT DISTINCT number
FROM temp1
) t

Find rows which are in a row with comma separated values same table sql

i have a table which contains comma separated values some thing like
id locs
1 a,s,d,f
2 s,d,f,a
3 d,s,a,f
4 d,f,g,a
5 a,s,e
6 f,d
i need out put as 1,2,3,6 in sql server when i have taken comma separated string of id 1.
that means i have taken locs of id 1 and separated with comma, now i want all the ids which contains the separated values of id 1.
Note: I know i don't have to keep comma separated values in table but its happened.
Hope i was clear with my question.
declare #tb table (id int, locs varchar(50))
insert into #tb values(1, 'a,s,d,f'),
(2,'s,d,f,a'),
(3,'d,s,a,f'),
(4,'d,f,g,a'),
(5,'a,s,e'),
(6,'f,d')
declare #cta varchar(20)='s,d,f,a'
;with cte0(id,col2)
as
(
select id,t.c.value('.','varchar(max)') as col2 from (select id,x= cast('<t>'+replace(locs,',','</t><t>') +'</t>' as xml) from #tb) a cross apply x.nodes('/t') t(c)
)
select distinct id from cte0 where #cta like '%'+col2+'%' and id not in( select distinct id from cte0 where #cta not like '%'+col2+'%')
If I understand you correctly, you need to return the id value of all the rows that has at least one of the comma separated values from the locs column of the row you selected. Since this is a poor database design there can only be an ugly solution to this problem.
Start by creating a user defined function to split a comma separated values into a table. there are many ways to do it, this is the first that google found.
DECLARE #Values varchar(max)
SELECT #Values = Locs
FROM Table WHERE Id = #Id
SELECT Id
FROM Table INNER JOIN dbo.Split(#Values) SplitedString
ON( '%,'+ SplitedString.s+',%' LIKE ',' + Locs + ',')

Trying to concatenate across records [duplicate]

This question already has answers here:
SQL group_concat function in SQL Server [duplicate]
(4 answers)
Closed 8 years ago.
I'm having a bit of a problem that I just can't seem to get my head round. I've got a table that I'm trying to extract some data from. Below is an example of the data.
Id DevId Route
1 1 1
2 1 2
3 1 3
4 1 4
5 2 1
6 2 2
What I want the result to look like would be:
DevId Route
1 1234
2 12
Don't know if I've been looking at it for too long or something, but I just can't work out how to do it.
Any help or suggestions would be greatly appreciated.
Thanks
Alex
Create table ##tmp (id int, name int)
insert into ##tmp values(1,1)
insert into ##tmp values(1,2)
insert into ##tmp values(1,3)
insert into ##tmp values(2,1)
insert into ##tmp values(2,2)
Select id, (Select cast (name as varchar(4))
from ##tmp t2
where t1.id = t2.id
for xml path('')
)
from ##tmp t1
group by id
drop table ##tmp

Pivot or Cross Tab [duplicate]

This question already has answers here:
Pivot in sql server
(4 answers)
Closed 8 years ago.
I have the two tables which need to be linked and present the data in human friendly way. Could you experts point me in right direction, I am bit stuck here.
Both table 1 and table2 are received through ftp and loaded to SQL table in SQL 2008 R2. These two tables are linked by nid and cid together.
Apologies i couldn't copy paste table here, please consider "-" are column separators
Table 1
ID nid cid pid form_key-name
1 4 1 33 Import_Gen_Title-Title
2 4 2 33 Import_Gen_Firstname-Firstname
3 4 3 33 Import_Gen_Surname-Surname
4 4 4 33 Import_Gen_AddressLine1-AddressLine1
5 4 5 33 Import_Gen_AddressLine2-AddressLine2
6 4 6 33 Import_Gen_City-Town/City
7 4 7 33 Import_Gen_Zip-Post code
Table 2
ID nid sid cid data
1 4 14 1 Mr
2 4 14 2 John
3 4 14 3 Smith
4 4 14 4 A Company
5 4 14 5 Nice Street
6 4 14 6 London
7 4 14 7 SE11 0TS
Now how can get this a Result Table like this one below ?
NiD SID Title Firstname Surname AddressLine1 AddressLine2 Town/City-Post code
4 14 Mr John Smith A Company Nice Street London-SE11 0TS
Check my answer for this same question here: Pivot in sql server
I made a stored procedure that uses the PIVOT statement shown by salvoo - but it's more generic, you don't have to know all the columns in advance.
Take a look.
Here is the example using your data - note that the default output of the pivot has the columns in alphabetical order which you don't want - so I used the option to output the pivot to a temp table then queried directly from the temp table to put the columns in the order you wanted.
drop table Fields
go
drop table Data
go
create table Fields
(
ID Integer,
nid Integer,
cid Integer,
pid Integer,
form_key_name varchar(50)
);
go
create table Data
(
ID Integer,
nid Integer,
sid Integer,
cid Integer,
data varchar(50)
);
go
insert into Fields values (1,4,1,33,'Import_Gen_Title-Title')
go
insert into Fields values (2,4,2,33,'Import_Gen_Firstname-Firstname')
go
insert into Fields values (3,4,3,33,'Import_Gen_Surname-Surname')
go
insert into Fields values (4,4,4,33,'Import_Gen_AddressLine1-AddressLine1')
go
insert into Fields values (5,4,5,33,'Import_Gen_AddressLine2-AddressLine2')
go
insert into Fields values (6,4,6,33,'Import_Gen_City-Town/City')
go
insert into Fields values (7,4,7,33,'Import_Gen_Zip-Post code')
go
insert into Data values (1,4,14,1,'Mr')
go
insert into Data values (2,4,14,2,'John')
go
insert into Data values (3,4,14,3,'Smith')
go
insert into Data values (4,4,14,4,'A Company')
go
insert into Data values (5,4,14,5,'Nice Street')
go
insert into Data values (6,4,14,6,'London')
go
insert into Data values (7,4,14,7,'SE11 0TS')
go
declare #mySQL varchar(MAX);
set #mySQL = '
select
f.nid,
d.sid,
right(f.form_key_name, len(f.form_key_name) - charindex(''-'',f.form_key_name)) form_key_name,
d.data
from
Fields f
JOIN Data d
on ( d.nid = f.nid
and d.cid = f.cid )
';
exec pivot_query #mySQL, 'nid, sid', 'form_key_name','max(data)', '##tmppivot';
select
nid,
sid,
Title,
Firstname,
Surname,
AddressLine1,
AddressLine2,
[Town/City],
[Post code]
from
##tmppivot;
go
With Pivot: Fiddle demo
SELECT sid, nid,
[Import_Gen_Title-Title] as Title,
[Import_Gen_Firstname-Firstname] as Name,
[Import_Gen_Surname-Surname] as SurName,
[Import_Gen_AddressLine1-AddressLine1] as Address1,
[Import_Gen_AddressLine2-AddressLine2] as Address2,
[Import_Gen_City-Town/City] as Town,
[Import_Gen_Zip-Post code] as PostCode
FROM
(
SELECT t2.sid, t2.nid, t2.dat, t1.form_key
FROM tab1 t1 INNER JOIN tab2 t2 ON t1.nid = t2.nid AND t1.cid = t2.cid
) x
PIVOT
(
min(x.dat)
for x.form_key in ([Import_Gen_Title-Title],
[Import_Gen_Firstname-Firstname],
[Import_Gen_Surname-Surname],
[Import_Gen_AddressLine1-AddressLine1],
[Import_Gen_AddressLine2-AddressLine2],
[Import_Gen_City-Town/City],
[Import_Gen_Zip-Post code]
)
) pvt
Edit (Added generic version): Fiddle demo
DECLARE #cols AS NVARCHAR(MAX),
#query AS NVARCHAR(MAX);
SET #cols = STUFF((SELECT ',[' + t.form_key + ']'
FROM tab1 t
group by t.form_key, cid
order by t.cid
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)'),1,1,'');
SET #query = 'SELECT * FROM
(
SELECT t2.sid, t2.nid, t2.dat, t1.form_key
FROM tab1 t1 INNER JOIN tab2 t2 ON t1.nid = t2.nid AND t1.cid = t2.cid
) x
PIVOT
(
min(x.dat)
FOR x.form_key IN (' + #cols + ')
) pvt;';
execute(#query);

Order By for NVARCHAR column in SQL Server

I have a NVARCHAR(255) column in a SQL Server 2005 that contain either letters or numbers.
Declare #Temp Table(Name NVARCHAR(255))
Insert Into #Temp Values('1')
Insert Into #Temp Values('2')
Insert Into #Temp Values('3')
Insert Into #Temp Values('10')
Insert Into #Temp Values('aaaa')
Insert Into #Temp Values('ccaaaaa')
Insert Into #Temp Values('cca')
Insert Into #Temp Values('cccc')
Insert Into #Temp Values('ccaa')
Select * From #Temp Order by Name
This query returns bad result. Can somebody explain why?
Also, can somebody tell me which query to use to sort values.
I want to get next sequence:
1
2
3
10
aaaa
cca
ccaa
ccaaaaa
cccc
Thanks
#Shark showed you why, I'll show you a work around in your SELECT to get you the results you want:
Select * From #Temp
Order by
case isnumeric(name)
when 1 then cast(name as int)
else 999999999999999 end,
name
The actual order of results will be this:
1
10
2
3
aaaa
cca
ccaa
ccaaaaa
cccc
And SQL Server is sorting it like that because it is getting sorted based on their character values. In other words, the character 1 comes before 2, as 10 will also come before 2.
So the reason you're getting odd sorting is because your are ordering by string values, not numeric.
EDIT: Please see Adrian's answer to the workaround.