Convert multiple rows into one with coma as separator [duplicate] - sql

This question already has answers here:
How to create a SQL Server function to "join" multiple rows from a subquery into a single delimited field? [duplicate]
(13 answers)
Closed 7 years ago.
If I issue SELECT ID FROM TestAhmet I get this result:
1
3
5
2
4
but what I really need is one row with all the values separated by comma, like this:
1,2,3,4,5
How do I do this?
ps: I cant do this : Convert multiple rows into one with comma as separator

If id is numeric column then do like this
select stuff((select ',' +Convert(varchar(50),id)
from TestAhmet
for xml path ('')
), 1, 1, '') as users

This should work:
select stuff((select ',' + cast(id as varchar(8000))
from TestAhmet
for xml path ('')
), 1, 1, '') as users
This is a variation on the string aggregation logic often used in SQL Server. But, without a group by, you probably won't find many examples on the web.

Related

SQL distinct columns with a concat of unique [duplicate]

This question already has answers here:
Simulating group_concat MySQL function in Microsoft SQL Server 2005?
(12 answers)
Closed 6 years ago.
In SQL Server, I have a simple view called v_master_server_list.
Server entries have multiple group memberships, so the servers will be duplicated in the view for every group membership. I need to return only a single row with the distinct server names and for every group membership, I'd like this concatenated with some kind of delimiter like '|' or ','
I've come up with this (thanks for the link), and I had to scrub out the null entries otherwise the LEN and LEFT functions wouldn't work. Question is, how do I now return all entries (even if nothing is found in 'arms_group')?
select server, LEFT(column_names, LEN(column_names )-1) AS column_names
from cmdb.[dbo].v_master_server_list AS extern
CROSS APPLY
(
select arms_group + ','
FROM cmdb.[dbo].v_master_server_list AS intern
where extern.server = intern.server
FOR XML PATH('')
) pre_trimmed (column_names)
where arms_group is not null
GROUP BY server, column_names;
You can use for xml to Concatenate Row Values in Transact-SQL
select distinct
group_membership
, servers = stuff(
(
select distinct '|'+i.server_name
from v_master_server_list as i
where i.group_membership = o.group_membership
order by i.server_name
for xml path (''), type).value('.','varchar(max)')
,1,1,'')
from v_master_server_list as o
In Sql Server vNext, you can use string_agg()

MS SQL - group by concat string [duplicate]

This question already has answers here:
Simulating group_concat MySQL function in Microsoft SQL Server 2005?
(12 answers)
Closed 6 years ago.
I am new to writing SQL scripts (at least anything more than SELECT * FROM X). I have run into a problem grouping a table by one value, and then joining values from another column into a single string.
I would like to perform a group by on a temp table, and then concatenate values of a column in the group together.
The table variable (edit), #categoriesToAdd, data structure is [SubscriberId int, CategoryId int].
What I am trying to do is something like (My understanding is that CONCAT is the bit missing from MSSQL):
SELECT SubscriberId,
CONCAT(CONVERT(VARCHAR(10), CategoryId) + ', ') as categoriesAdded
FROM #categoriesToAdd
GROUP BY SubscriberId
The concatenated category IDs for each subscriber would then look something like:
0001, 0002, 0003, 0004
Thanks!
In sql server you can use FOR XML PATH
select SubscriberId,
categoriesAdded=Stuff((SELECT ',' + CAST(CategoryId as VARCHAR(255)) FROM catsToAdd t1 WHERE t1.SubscriberId=#categoriesToAdd.SubscriberId
FOR XML PATH (''))
, 1, 1, '' )
from #categoriesToAdd as catsToAdd
GROUP BY SubscriberId

Merging of fields using xml path in sql server, display comma where NULL

I have a table in which two or more different dates are listed for a single id. I want to merge all the dates for a single id. Example code is as below.
create table number(id nvarchar(255), billdate nvarchar(255))
insert into number(id,billdate) values ('56465','12/10/2011'),('56465','02/11/2011'),
('46462','12/09/2009'),('46462','12/06/2010'),('32169','12/22/2009'),
('32169','12/31/2011'),('86835','12/10/2010'),('86835','22-Jan-2010'),
('65641',''),('65641','12-Aug-2009'),('22458','25-Aug-2007'),('22458','')
For merging the rows I am using xml path as below
select Main.id,LEFT(Main.billdate,nullif(LEN(Main.billdate)-1,-1)) as "billdate"
from (select distinct ST2.id,(SELECT ST1.billdate + ',' AS [text()]
from NUMBER ST1 where ST1.id=ST2.id ORDER BY ST1.id FOR XML PATH (''))billdate
from NUMBER ST2)[Main]
It is working perfectly for this sample data, But the Problem is I have huge data, and when I apply this XML path code a comma is not displayed if a date is NULL, like for the id 65641. Its important for me to display a comma in the place of NULL. Where am I going wrong? Can anyone suggest why it's not displaying a comma in the place of NULL?
I'm not sure I perfectly understand you, since the putatively NULL value for 65641 is actually a blank. To treat NULL values like blanks, you can use this:
select Main.id,LEFT(Main.billdate,nullif(LEN(Main.billdate)-1,-1)) as "billdate"
from
(
select distinct ST2.id,
(
SELECT ISNULL(ST1.billdate + ',', ',') AS [text()]
from NUMBER ST1
where ST1.id=ST2.id
ORDER BY ST1.id
FOR XML PATH ('')
) billdate
from NUMBER ST2
)[Main]
The other issue you might be having is that if there is only a single blank/NULL value for a given id, you don't get even a single comma for it. This is happening because a single blank value only generates a single comma, which is then stripped off by your LEFT statement. You can make it leave single commas alone by changing it like so:
select Main.id,LEFT(Main.billdate,nullif(LEN(Main.billdate)-CASE WHEN LEN(Main.billdate) = 1 THEN 0 ELSE 1 END,-1)) as "billdate"
from
(
select distinct ST2.id,
(
SELECT ISNULL(ST1.billdate + ',', ',') AS [text()]
from NUMBER ST1
where ST1.id=ST2.id
ORDER BY ST1.id
FOR XML PATH ('')
) billdate
from NUMBER ST2
)[Main]
You still have issues, one of which is that you have no explicit ordering of dates, but I hope that covers the problems that you have. If not, clarify and I'll attempt to help some more.

Concatinating Rows Specific Field and Displaying the Concatinated Value in SELECT query-SQL [duplicate]

This question already has answers here:
Simulating group_concat MySQL function in Microsoft SQL Server 2005?
(12 answers)
Closed 8 years ago.
My aim is to display the person name and all the reason for his absences(concated and displaying in a string).
I am using the following query to display the EmployeeName, ReasonForAbsence. I am having problem with concatenating and Displaying all record specific column called 'AbsenceReason'. The error is Incorrect Syntax near ='. More info about error- its happening for displaying absence reason part.
SELECT
--Displaying Name,
EMP.NAME,
--Displaying Absence Reason
(
SELECT
#AbsenceReasons= #AbsenceReasons + ';' + REASONTEXT
FROM
ABSENCE
WHERE ID=EMP.ID
)
FROM
(
SELECT
*
FROM
Employees
) EMP
What have I missed?
Thank you
As Martin says this is a duplicated question but...
SELECT DISTINCT Absence.EmpId, Reasons.AllReasons
FROM Absence
CROSS APPLY ( SELECT ReasonText + ' ,'
FROM Absence EMP2
WHERE EMP2.EmpId= Absence.EmpId
FOR XML PATH('')
) Reasons ( AllReasons)

How can I pull a list of ID's from a SQL table as a comma-separated values string?

I have to pull a list of integer IDs from a table using only records that match some criteria. For example:
Select ProdID From Products Where (ProdType='XYZ');
The catch is that I have to return it as a set of comma separated values so I can use it to select items in a multi-select list:
111,231,554,112
rather than as records. I do not want to do this in my C# code - I'd like it to come right out of the database via a query this way. Any ideas?
MySQL
SELECT GROUP_CONCAT(t.prodid SEPARATOR ',')
FROM PRODUCTS t
WHERE t.prodtype = 'XYZ'
Oracle:
There is an excellent summary of the available string aggregation techniques on Tim Hall's site.
SQL Server 2005+
SELECT STUFF((SELECT ','+ t.prodid
FROM PRODUCTS t
WHERE t.prodtype = 'XYZ'
FOR XML PATH('')), 1, 1, '')
In addition to #OMG Ponies method, you could also try this COALESCE trick from:
Using COALESCE to Build Comma-Delimited Strings
declare #string nvarchar(255)
select #string = coalesce(#string + ', ', '') + cast(prodid as nvarchar(5))
from products
From SQL Server 2017 onwards, you can now use the STRING_AGG function.
This allows you to create the comma-separated list from within the SELECT statement (so works nicely with views). Given your example, it will become:
SELECT STRING_AGG(ProdID, ',')
FROM Products
WHERE (ProdType='XYZ');
This is a very old question but I'm adding an answer that applies the already-accepted answer using COALESCE by Justin Niessner. This application is how I would normally want to apply this technique where I'm querying a parent and I want to also have a single column which contains a comma-delimited list of child IDs.
These examples go against an AdventureWorksLT database as created in Azure SQL Database if you use the dropdown to select it when you provision a database. Nothing new here, just a convenient application that might help somebody.
The first query is how I'll normally use it:
SELECT
SalesLT.ProductCategory.*,
STUFF((SELECT ','+ cast(ProductID as nvarchar(10)) FROM SalesLT.Product WHERE ProductCategoryID=SalesLT.ProductCategory.ProductCategoryID ORDER BY ProductID FOR XML PATH('')), 1, 1, '') AS ProductIDs
FROM SalesLT.ProductCategory
The second query shows a self-referencing use of it:
SELECT
ParentCategory.*,
STUFF((SELECT ','+ cast(child.ProductCategoryID as nvarchar(10)) FROM SalesLT.ProductCategory child WHERE child.ParentProductCategoryID=ParentCategory.ProductCategoryID ORDER BY child.ProductCategoryID FOR XML PATH('')), 1, 1, '') AS ChildCategoryIDs
FROM SalesLT.ProductCategory ParentCategory
WHERE
EXISTS (SELECT ParentProductCategoryID FROM SalesLT.ProductCategory children WHERE children.ParentProductCategoryID=ParentCategory.ProductCategoryID)
For SQL server see here: Concatenate Values From Multiple Rows Into One Column
Theres a way to do it without additional functions:
DECLARE #Test nvarchar(max) = ''
SELECT #Test = #Test + ProdID + ', '
FROM Products
WHERE (ProdType='XYZ')
SELECT #Test
#Test will contain a list of your IDs, although I cannot explain why this works.
For the future PostgreSQL users, please find the solution below (it is the same as #Matt Tester answered.
SELECT STRING_AGG(cast(id as varchar), ',') from table1
where col1 = 'ABC';
Please note that the cast is required if the column you are selecting is not string (or varchar in database terms).