如何在 SQL Server 中连接字符串,并按不同的列排序/排序?
Posted
技术标签:
【中文标题】如何在 SQL Server 中连接字符串,并按不同的列排序/排序?【英文标题】:How to concatenate strings in SQL Server, and sort/ order by a different column? 【发布时间】:2019-12-25 08:58:21 【问题描述】:我在 SQL Server 中看到了许多连接字符串的示例,但如果他们担心排序,则总是通过连接的列。 我需要根据不同字段中的数据对值进行排序。
示例表:
ClassID | StudentName | SortOrder
-----------------------------
A |James |1
A |Janice |3
A |Leonard |2
B |Luke |2
B |Leia |1
B |Artoo |3
而我想要得到的结果是:
ClassID |StudentName
--------------------------------
A |James, Leonard, Janice
B |Leia, Luke, Artoo
如何在 SQL Server 2016 中做到这一点? (我期待 2017 年的 STRING_AGG,但我们还没有……)
谢谢!
【问题讨论】:
尝试先排序(考虑 WITH 子句)然后聚合 在Sql中使用window函数 【参考方案1】:给你:
SELECT
s1.ClassID
, STUFF((SELECT
',' + s2.StudentName
FROM dbo.Student AS s2
WHERE s1.classID = s2.ClassID
ORDER BY s2.SortOrder
FOR XML PATH('')), 1, 1, '') AS StudentNames
FROM dbo.Student AS s1
GROUP BY s1.ClassID
【讨论】:
但是下一次,请不要以图像而是以文本形式提交您的示例数据和结果:) 效果很好,谢谢! (下次我一定会以文本形式提交示例数据) 我编辑了问题以包含内联样本而不是图像;-)【参考方案2】:SQL Fiddle
MS SQL Server 2017 架构设置:
CREATE TABLE MyTable(ClassID varchar(255),StudentName varchar(255),SortOrder int)
INSERT INTO MyTable(ClassID,StudentName,SortOrder)VALUES('A','James',1),('A','Janice',3),('A','Leonard',2),
('B','Luke',2),('B','Lela',1),('B','Artoo',3)
查询 1:
SELECT
t.ClassID
, STUFF((SELECT
',' + t1.StudentName
FROM MyTable t1
WHERE t.classID = t1.ClassID
ORDER BY t1.SortOrder
FOR XML PATH('')), 1, 1, '') AS StudentNamesConcat
FROM MyTable AS t
GROUP BY t.ClassID
Results:
| ClassID | StudentNamesConcat |
|---------|----------------------|
| A | James,Leonard,Janice |
| B | Lela,Luke,Artoo |
【讨论】:
【参考方案3】:这里是查询
IF OBJECT_ID('tempdb..#Temp') IS NOT NULL DROP TABLE #Temp;
CREATE TABLE #Temp(ClassId varchar(10),studName varchar(100),SortOrder int)
INSERT INTO #Temp(ClassId , studName, SortOrder)
SELECT 'A','James',1 UNION ALL
SELECT 'A','Janice',3UNION ALL
SELECT 'A','Leonard',2 UNION ALL
SELECT 'B','Luke',2 UNION ALL
SELECT 'B','Leia',1 UNION ALL
SELECT 'B','Artoo',3
-- select * from #Temp
select
distinct
stuff((
select ',' + u.studName
from #Temp u
where u.studName = studName and U.ClassId = L.ClassId
order by u.SortOrder
for xml path('')
),1,1,'') as userlist,ClassId
from #Temp L
group by ClassId
【讨论】:
【参考方案4】:您也可以尝试使用 PIVOT。这将支持更旧版本的 SQL Server。 唯一限制:您应该知道最大的 SortOrder 值。下面的代码适用于任何 ClassID 的 SortOrder
SELECT ClassID, ISNULL([1],'') +ISNULL(', '+[2],'')+ISNULL(', '+[3],'')+ISNULL(', '+
[4],'')+ISNULL(', '+[5],'')+ISNULL(', '+[6],'')+ISNULL(', '+[7],'')+ISNULL(', '+
[8],'')+ISNULL(', '+[9],'')+ISNULL(', '+[10],'')+ISNULL(', '+[11],'')+ISNULL(', '+
[12],'')+ISNULL(', '+[13],'')+ISNULL(', '+[14],'')+ISNULL(', '+[15],'')+ISNULL(', '+
[16],'')+ISNULL(', '+[17],'')+ISNULL(', '+[18],'')+ISNULL(', '+[19],'')+ISNULL(', '+
[20],'') AS StudentName
FROM
(SELECT SortOrder,ClassID,StudentName
FROM [Table1] A
) AS SourceTable
PIVOT
(
MAX(StudentName)
FOR SortOrder IN ([1],[2],[3],[4],[5],[6],[7],[8],[9],[10],[11],[12],[13],[14],[15],[16],[17],[18],[19],[20])
) AS PivotTable
【讨论】:
以上是关于如何在 SQL Server 中连接字符串,并按不同的列排序/排序?的主要内容,如果未能解决你的问题,请参考以下文章
如何在 sql server 2008 的同一张表中使用计数和分组方式和自连接?
如何将行旋转为列,并按过去 7 天显示 - SQL SERVER