McN*_*ets 5 sql-server order-by csv
给定这样的架构:
CREATE TABLE Foo
(
Id int PRIMARY KEY,
Position int NOT NULL,
Title varchar(10) NOT NULL
);
INSERT INTO Foo VALUES
(1, 3, 'Title3'),
(2, 10, 'Title10'),
(3, 1, 'Title1'),
(4, 12, 'Title12'),
(5, 2, 'Title2');
Run Code Online (Sandbox Code Playgroud)
我需要生成一个逗号分隔的字符串,按Position以下顺序排序:
'M' + Id + ' AS [' + Title + ']'
Run Code Online (Sandbox Code Playgroud)
想要的结果:
M1 AS [Title1], M2 AS [Title10], M3 AS [Title3], M4 AS [Title10], M5 AS [Title12]
Run Code Online (Sandbox Code Playgroud)
我试过了:
DECLARE @rows nvarchar(max);
SET @rows = STUFF((SELECT DISTINCT ', ' + ('M' + CAST(Id as varchar(10)) + ' AS ' + QUOTENAME(Title))
FROM Foo
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(MAX)')
,1,1,'');
SELECT @rows;
Run Code Online (Sandbox Code Playgroud)
但它构建按以下顺序排列的结果Id:
M1 AS [Title3], M2 AS [Title10], M3 AS [Title1], M4 AS [Title12], M5 AS [Title2]
Run Code Online (Sandbox Code Playgroud)
如果我添加ORDER BY Id到STUFF表达式:
DECLARE @rows nvarchar(max);
SET @rows = STUFF((SELECT DISTINCT ', ' + ('M' + CAST(Id as varchar(10)) + ' AS ' + QUOTENAME(Title))
FROM Foo
ORDER BY Position
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(MAX)')
,1,1,'');
SELECT @rows;
Run Code Online (Sandbox Code Playgroud)
产生下一个错误:
Msg 145 Level 15 State 1 Line 2
ORDER BY 项必须出现在选择列表中,如果指定了 SELECT DISTINCT。+
我可以使用按以下顺序排序的子查询Position:
DECLARE @rows nvarchar(max);
SET @rows = STUFF((SELECT DISTINCT ', ' + ('M' + CAST(Id as varchar(10)) + ' AS ' + QUOTENAME(Title))
FROM (SELECT TOP 100 PERCENT Id, Position, Title FROM Foo ORDER BY Position) X
FOR XML PATH(''), TYPE
).value('.', 'nvarchar(MAX)')
,1,1,'');
SELECT @rows;
M1 AS [Title3], M2 AS [Title10], M3 AS [Title1], M4 AS [Title12], M5 AS [Title2]
Run Code Online (Sandbox Code Playgroud)
但我想知道是否有另一种方法可以在不使用子查询的情况下对结果进行排序。没有重复的标题。
dbfiddle在这里
正如Aaron Bertrand在评论中指出的那样,产生错误是因为我正在使用SELECT DISTINCT; 在这个例子中,这是没有必要的。此外,ORDER BY如果删除了不同值,则位置完全有效。
如果DISTINCT删除,查询将返回所需的值:
Run Code Online (Sandbox Code Playgroud)DECLARE @rows nvarchar(max); SET @rows = STUFF((SELECT ', ' + ('M' + CAST(Id as varchar(10)) + ' AS ' + QUOTENAME(Title)) FROM Foo ORDER BY Position FOR XML PATH(''), TYPE ).value('.', 'nvarchar(MAX)') ,1,1,''); SELECT @rows; GO| (无列名)| | :---------------------------------------------------------------- ------------------------------------------- | | M3 AS [标题 1]、M5 AS [标题 2]、M1 AS [标题 3]、M2 AS [标题 10]、M4 AS [标题 12] |
dbfiddle在这里
我建议看一下sp_BlitzErik推荐的这篇文章: