SQL row values to one column [duplicate] - sql

This question already has answers here:
How to concatenate text from multiple rows into a single text string in SQL Server
(47 answers)
Closed 2 years ago.
I have a SQL query which return the below data;
I need to write Values to one row depend ID and Code column like below;

SELECT ID, Code, STRING_AGG(Value) AS Value
FROM dbo.Table
GROUP BY ID, Code;
Considering you're using up to date version.

Please check below attempt. There are other options also you can use.
SELECT
CAST(408 AS INT) AS ID,
CAST(1 AS INT) AS CODE,
CAST('A' AS VARCHAR(20)) AS VALUE
INTO
#tmpgroupby
INSERT INTO #tmpgroupby
VALUES
(408,1,'B'),
(408,1,'C'),
(408,1,'D'),
(408,1,'E'),
(408,1,'F'),
(408,1,'G'),
(408,2,'H'),
(408,2,'I'),
(408,2,'J'),
(408,2,'K')
SELECT ID,CODE, STUFF(
(SELECT ', ' + convert(varchar(10), t2.VALUE, 120)
FROM #tmpgroupby t2
where t1.ID = t2.ID
AND t1.code = t2.CODE
FOR XML PATH (''))
, 1, 1, '')
FROM #tmpgroupby t1
GROUP BY ID,CODE
--- below also give the same result
SELECT ID, Code, STRING_AGG(VALUE,',') AS Value
FROM dbo.#tmpgroupby
GROUP BY ID, Code;
DROP TABLE #tmpgroupby

For Sql Server:
SELECT ID, CODE,
Value=STUFF((SELECT distinct ',' + Value FROM table_name t1
WHERE t.Code = t1.Code FOR XML PATH ('')), 1, 1, '')
FROM table_name AS t
GROUP BY ID, Code

Related

Progress 12.2 - Concat rows with same ID

I use the database Progress 12.2 and I want to group rows with same id
For example I have
ID Code
1 PB
1 RO
And I want :
ID Code
1 PB, RO
This is my request :
SELECT id, code FROM table WHERE table.id = 1
I tried String_agg, Group_concat ... but nothing works. Anyone has an idea ?
Regards,
You can use someting like that;
DECLARE #TBL TABLE (ID Int, Code nvarchar(5))
INSERT INTO #TBL values (1 ,'PB'),(1 ,'RO')
SELECT DISTINCT
T1.ID,
CONCAT_STRING = STUFF((
SELECT ',' + T2.Code
FROM #TBL T2
WHERE T2.ID = T1.ID
FOR XML PATH(''), TYPE).value('.', 'NVARCHAR(MAX)'), 1, 1, '')
FROM #TBL T1
The result will be like this;

Improve performance of SQL query with a FOR XML PATH in SQL Server 2008

I am trying to concatenate LoadIds for a user using For XML path which is a portion of my whole query, I verified that the maximum time gets elapsed in calculating this concatenated LoadId column. Below is the syntax, can anyone suggest a way to rewrite this efficiently?
SELECT
Col1, col2,
LoadIds = STUFF((SELECT ' , ' + CAST([LoadId] AS varchar(5))
FROM Table1 AS t1
WHERE t1.[UserId] = [t2].[UserId]
FOR XML PATH ('')), 1, 2, '')
FROM
Table1 AS t2
GROUP BY
[UserId]
1). I would try to collect the required data in a temp table or table variable, create an index on it and then play with the concatination.
2). FOR XML PATH works good for small sets of records, for large sets I would try a recursion.
declare #T table (
UserId int not null,
RowNumber int not null,
LoadId varchar(5) not null
primary key clustered (UserId, RowNumber)
);
insert into #T
select
UserId,
row_number() over(partition by UserId order by LoadId),
CAST(LoadId AS varchar(5))
from
Table1 ;
with cte (UserId, RowNumber, LoadIds) as
(
select
UserId,
RowNumber,
LoadIds = convert(varchar(8000), LoadId)
from #T
where RowNumber = 1
union all
select
t.UserId,
t.RowNumber,
convert(varchar(8000), cte.LoadIds + ', ' + t.LoadId)
from
cte inner join #T t on t.UserId = cte.UserId and t.RowNumber = cte.RowNumber + 1
)
select UserId, LoadIds = max(LoadIds) from cte group by UserId;
One thing you can do is select the distinct user ids before doing the string aggregation:
SELECT t2.UserId,
STUFF((SELECT ' , ' + CAST([LoadId] AS varchar(8000))
FROM Table1 t1
WHERE t1.[UserId] = [t2].[UserId]
FOR xml PATH ('')
), 1, 2, ''
) as LoadIds
FROM (SELECT DISTINCT userId
FROM Table1 t2
) t2;
For performance, an index on table1(UserId, LoadId) would also help.

SQL Qry required to get a comma separated string from a table [duplicate]

This question already has answers here:
How to concatenate text from multiple rows into a single text string in SQL Server
(47 answers)
Closed 5 years ago.
In my database there is a table with values below
image attached
In need a qry to get the result like this
DECLARE #TAB TABLE(SIDS INT,VALUE VARCHAR(10))
INSERT INTO #TAB
SELECT 1,'ASC'
UNION ALL
SELECT 1,'ASC'
UNION ALL
SELECT 1,'ASC'
UNION ALL
SELECT 2,'SDF'
UNION ALL
SELECT 2,'SFD'
UNION ALL
SELECT 3,'ERF'
UNION ALL
SELECT 3,'ERF1'
SELECT T1.SIDS,VALUE = STUFF((SELECT ','+T2.VALUE FROM #TAB T2 WHERE T1.SIDS = T2.SIDS FOR XML PATH('')),1,1,'')
FROM #TAB T1
GROUP BY T1.SIDS
OUTPUT
SIDS VALUE
1 ASC,ASC,ASC
2 SDF,SFD
3 ERF,ERF1
Use XML query as below;
DECLARE #tblQuestion AS Table
(
SID INT,
Value VARCHAR(50)
)
INSERT INTO #tblQuestion VALUES(1,'stu')
INSERT INTO #tblQuestion VALUES(1,'vtu')
INSERT INTO #tblQuestion VALUES(1,'ztu')
INSERT INTO #tblQuestion VALUES(2,'stu')
INSERT INTO #tblQuestion VALUES(2,'vtu')
select distinct t.SID,
STUFF((SELECT distinct ', ' + t1.Value
from #tblQuestion t1
where t.SID = t1.SID
FOR XML PATH(''), TYPE
).value('.', 'NVARCHAR(MAX)')
,1,2,'') Value
from #tblQuestion t;
Output:

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

How to make 2 rows into single row in sql

I have a query
example
Title Description
A XYZ
A ABC
now i want a sql query so that i can get a single row
Output :
Title Description
A XYZ | ABC
Declare #tbl table(Title nvarchar(1),[Description] nvarchar(100))
Insert into #tbl values('A','XYZ');
Insert into #tbl values('A','ABC');
Insert into #tbl values('A','PQR');
DECLARE #CSVList varchar(100)
SELECT #CSVList = COALESCE(#CSVList + ' | ', '') +
[Description]
FROM #tbl
WHERE Title='A'
SELECT #CSVList
declare #table table (i int, a varchar(10))
insert into #table
select 1, 'ABC' union all
select 1, 'XYZ' union all
select 2, '123'
select t.i,
max(stuff(d.i, 1, 1, '')) [iList]
from #table t
cross
apply ( select '|' + a
from #table [tt]
where t.i = tt.i
for xml path('')
) as d(i)
group
by t.i;
In mysql there is a group_concat function, that can help you.
Use it like this:
SELECT Title,GROUP_CONCAT(Description) FROM table_name GROUP BY Title
The output will be
Title Description
A XYZ,ABC
Then you can replace "," with "|" if you want(it can be done with replace function)
For 2 rows you can self join in SQL Server. This avoids the assorted "concatenate rows into a column" tricks. You can use a LEFT JOIN and NULL handling too for 1 or 2 rows
SELECT
T1.Title,
T1.Description + '|' + T2.Description
FROM
MyTable T1
JOIN
MyTable T2 ON T1.Title = T2.Title
SELECT
T1.Title,
T1.Description + ISNULL('|' + T2.Description, '') --COALESCE for the pedants)
FROM
MyTable T1
LEFT JOIN
MyTable T2 ON T1.Title = T2.Title
If you are using SQL Server, try this: How to return 1 single row data from 2 different tables with dynamic contents in sql