Comma separated values in one column - SQL SERVER - sql

Customer Table
--------------
ID Name
1 James
2 Peter
Order Table
---------------
OrderId CustId
100 1
101 1
102 2
How can I write a query that returns something like this
ID,Name,ListofOrders
1,James,"100,101"
2,Peter,"102"
In Sybase I had a function called LIST which I could use but I dont find a similar function in SQL SERVER

Please try:
select ID, [Name],
(select OrderID+',' from OrderTable where CustID=ID
group by OrderID for xml path('')) AS ListOfOrders
From CustomerTable

Create a User Defined Function as shown below
CREATE FUNCTION [dbo].[CommaSeperatedOrderIDs](#CustId INT) returns varchar(Max)
AS
BEGIN
DECLARE #CommaSeperatedValues VARCHAR(MAX)
SELECT #CommaSeperatedValues = COALESCE(#CommaSeperatedValues+',' , '') + OrderID
FROM OrderTable WHERE CustId = #CustId
RETURN #CommaSeperatedValues
END
And then,
select ID, [Name], ([dbo].[CommaSeperatedOrderIDs](ID)) AS ListofOrders
From CustomerTable

Adding full details from Sheikh Haris' link.
Given this table:
To get output like:
Use the following SQL:
SELECT field1,
Substring(convert(varchar(100),
(
SELECT (', ' + field2)
FROM #test t2
WHERE t1.field1 = t2.field1
ORDER BY field1, field2
FOR XML PATH( '' )
)), 3, 1000 )
FROM #test t1
GROUP BY field1
I added a convert function to the substring so that the WIDEMEMO field would be displayed (SQL Server)

A very simple and handy solution given on the link below.
http://tejasnshah.wordpress.com/2009/02/28/sql-server-get-column-values-as-comma-seperated-list-using-xml-path-instead-of-udfs-using-sql-coalesce/
The SQL query written on that link is in an image ...so i couldn't copy it here.

Related

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

Combine two rows into one row. like average function but instead it will concat

I'm using SQL Server 2000.
What I want to do is like average function but instead it will concat.
Is there a way that I can do that?
For example I have this data.
Name | Score
Name1 | 50
Name1 | 70
and the output should be like this.
Name | Score
Name1 | 50,70
Use below query for your reference.
Query
Select main.doctorID,
Left(Main.submain,Len(Main.submain)-1) As 'Title'
From
(
Select distinct ST2.doctorID,
(
Select convert(varchar,ST1.encounterid) + ',' AS [text()]
From dbo.enc ST1
Where ST1.doctorID = ST2.doctorID
ORDER BY ST1.doctorID
For XML PATH ('')
) submain
From dbo.enc ST2
) [Main]
If you can use CLR, look at this example :
https://msdn.microsoft.com/en-us/library/ms165055%28v=vs.90%29.aspx
It provides a custom aggregate that concatenates values, which results in very clean code.
You can do it by this simple query.
Select Name, (Select SUBSTRING((SELECT ', '+Score from TableName for XML
Path('')) ,2,8000)) from TableName
You will have result like
ColumnName | val1, val2, ....
check this.
INSERT INTO #T VALUES
('name1', 50),
('name1', 70)
SELECT * FROM #T
Select name ,
STUFF((SELECT ',' + cast( score as varchar(50)) FROM #T WHERE (
name=Result.name) FOR XML PATH ('')),1,1,'') AS BATCHNOLIST
From #T AS Result
GROUP BY name
Can I Comma Delimit Multiple Rows Into One Column?
Query
SELECT Name,
(SELECT SUBSTRING((SELECT ', '+CAST(Score AS VARCHAR(MAX)) FROM my_table FOR XML Path('')) ,2,1000)) AS Score
FROM my_table
GROUP BY name;
Fiddle for reference
If you are using SQL Server 2000, then try to create a function as follows.
CREATE TABLE my_table(name VARCHAR(50),score INT);
INSERT INTO my_table VALUES('Name1',50);
INSERT INTO my_table VALUES('Name1',70);
Function
CREATE FUNCTION commaseparated(#name VARCHAR(MAX))
RETURNS VARCHAR(MAX)
AS
BEGIN
DECLARE #score VARCHAR(MAX)
SELECT #score = COALESCE(#score + ', ', '') + CAST(score AS VARCHAR(MAX))
FROM my_table
WHERE name = #name
RETURN #score
END
SELECT
name,
score = dbo.commaseparated(name)
FROM my_table
GROUP BY name;

How can I repeat a value from one column according to a value from another column?

I have data like below - one column with a value, the second with a count:
Name Count
----- -----
John 2
Smith 3
I want an output like below - each row consisting of the value in the first column repeated n times, where n is the value of the second column:
John,John
Smith,Smith,Smith
Is there a built-in Oracle function or SQL query that could be used to achieve this? If PL/SQL is required, that would also be helpful.
Looks to me that RPAD can do it
This is NOT TESTED as I don't have an Oracle db to hand
RPAD("", (LENGTH(name)+1)*count -1, name||',')
(rpad a blank string with count copies of the string, by requiring the result to be (length(name)+1)*count -1 long. The -1 is to remove the trailing comma )
Hat tip to OracleUser for the appending-the comma bit.
I'm not familiar with oracle, but if you know how to use recursion in oracle then you might be able to convert my T-SQL code to what works for you...
Step 1. Create test table containing your sample data:
CREATE TABLE #t ([Name] VARCHAR(20), [Count] INT);
INSERT INTO #t VALUES('John',2)
INSERT INTO #t VALUES('Smith',3)
SELECT * FROM #t
This gives the following output:
Name Count
-------------------- -----------
John 2
Smith 3
Step 2. Recursive Query to get desired output:
DECLARE #Separator VARCHAR(3); SET #Separator = ','
;WITH myCTE AS (
SELECT 1 AS [Count], [Name], [Count] AS RequiredCount, [Name] AS Result FROM #t
UNION ALL
SELECT [Count] + 1, [Name], RequiredCount, CAST(Result + #Separator + [Name] AS VARCHAR(20)) FROM myCTE WHERE RequiredCount > [Count]
)
SELECT [Count], [Name], Result FROM myCTE WHERE [Count] = RequiredCount
This gives the following output:
Count Name Result
----------- -------------------- --------------------
3 Smith Smith,Smith,Smith
2 John John,John
If this doesn't make sense to you, post a comment... I'll try and explain. I'm sure someone familiar with PL/SQL can help you convert this to meet your needs.
All the best!

fetch comma separated value in SQL query

Please check below table
Code Name
-----------
001 A
001 B
My query is
Select Code,Name from TableA
But I need records like
Code Name
------------
001 A,B
How can I do that?
Unlike MySQL, SQL Server doesn't have a built-in function for this but you can still simulate it by using CROSS APPLY and FOR XML PATH('')
SELECT a.Code,
SUBSTRING(d.[Name],1, LEN(d.[Name]) - 1) AddressList
FROM
(
SELECT DISTINCT Code
FROM TableA
) a
CROSS APPLY
(
SELECT [Name] + ', '
FROM TableA AS B
WHERE A.[Code] = B.[Code]
FOR XML PATH('')
) D ([Name]) ;
SQLFiddle Demo
You could use COALESCE. The following sample turns this
Hello
World
It's
Me
into this
Hello, World, It's, Me
DECLARE #test NVARCHAR(2000)
SELECT #test = COALESCE(#test + ', ', '') + Field FROM Sampletable WHERE … AND Field IS NOT NULL
SELECT #test
You should be able to adapt this to your sample.

SQL group records with same value, and place that into a table

I want to group same record with SQL, the following is my result
Name Code Qty
data1 AG 12
data1 AS 15
data2 MS 10
data2 IS 11
I want it to be like this instead.
Name Code Qty Code Qty
data1 AG 12 AS 15
data2 MS 10 IS 11
Can this be done in SQL only?
Can this be done in SQL only?
With a variable number of columns you have to build a the query dynamically.
I would hardly call this "SQL only" but it can be done in T-SQL and here is one way.
-- Sample table
declare #T table
(
Name varchar(5),
Code varchar(2),
Qty int
)
-- Sample data
insert into #T values
('data1', 'AG', 12),
('data1', 'AS', 15),
('data1', 'AQ', 17),
('data2', 'MS', 10),
('data2', 'IS', 11)
declare #XML xml
declare #SQL nvarchar(max)
declare #Max int
-- Max number of codes per name
select #Max = max(C)
from (select count(*) as C
from #T
group by Name) as T
-- Convert table to XML
set #XML = (select Name,
(select Code,
Qty
from #T as T2
where T1.Name = T2.Name
for xml path('c'), type)
from #T as T1
group by Name
for xml path('r'))
-- Build a dynamic query
;with Numbers(Number) as
(
select 1
union all
select Number + 1
from Numbers
where Number < #Max
)
select #SQL = 'select T.N.value(''Name[1]'', ''varchar(5)'') as Name ' +
(select ',T.N.value(''c['+cast(Number as nvarchar(10))+']/Code[1]'', ''char(2)'') as Code
,T.N.value(''c['+cast(Number as nvarchar(10))+']/Qty[1]'', ''int'') as Qty'
from Numbers
for xml path(''), type).value('.', 'nvarchar(max)') +
' from #xml.nodes(''/r'') as T(N)'
-- Execute query
exec sp_executesql #SQL, N'#xml xml', #XML
Result:
Name Code Qty Code Qty Code Qty
----- ---- ----------- ---- ----------- ---- -----------
data1 AG 12 AS 15 AQ 17
data2 MS 10 IS 11 NULL NULL
Try here: https://data.stackexchange.com/stackoverflow/q/122860/
Assuming you are using SQLServer, you could use rank to assign a sequential number to each code with the name group, like so:
select Name, Code, Qty, Rank() OVER (PARTITION BY Name ORDER BY Code) AS CodeRank
from MyTable
Then you can use the pivot functionality within either SQLServer or SSRS to format this as required.
Not exactly. You can hack around with the idea of concatenating lots of Code,Qty pairs into a single value for each record, though. I'm not sure what you're planning to do with multiple columns with the same name, even if such a thing were possible.