使用变量 Coalesce 排序
Order by with variable Coalesce
我有以下 sql 命令
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',['+ cast(Month as nvarchar(2))+']' , '['+ Cast(Month as nvarchar(2))+']')
FROM (select distinct Month from Employee WHERE Year*100+Month BETWEEN 201704 and 201712 ) as e
PRINT @cols
结果是
[9],[12],[6],[7],[10],[4],[5],[11],[8]
但我真的希望它按排序顺序排列
[4],[5],[6],[7],[8],[9],[10],[11],[12]
变量合并 is documented as being non-deterministic, and may cause incorrect results,特别是在存在 ORDER BY
的情况下。您也不能将 ORDER BY
放在派生的 table 或视图中,原因很明显:最终排序 仅 由外部查询确定。
您应该改为只使用 STRING_AGG
进行聚合。您可以使用 WITHIN GROUP (ORDER BY
来获取顺序。
另请注意:
- 始终使用
QUOTENAME
将列名括起来,而不是自己动手,因为转义可能很复杂。
- 最好对列进行精确比较,而不是对它们进行计算然后比较,因为这样您就可以命中索引(sarge-ability)。
- 最好将日期存储在实际的日期列中,而不是乱用多个列,但我会将数据库重新设计留给您
DECLARE @cols NVARCHAR(MAX) = (
SELECT STRING_AGG(QUOTENAME(Month), N',') WITHIN GROUP (ORDER BY Month)
FROM (
select distinct
Month
from Employee
WHERE Year = 2017
AND Month BETWEEN 4 AND 12
) as e
);
对于 SQL Server 2016 及更早版本,您可以使用旧的 FOR XML
方法:
DECLARE @cols NVARCHAR(MAX) = STUFF((
SELECT N',' + QUOTENAME(Month)
FROM (
select distinct
Month
from Employee
WHERE Year = 2017
AND Month BETWEEN 4 AND 12
) as e
ORDER BY Month
FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)')
, 1, LEN(N','), N'');
我有以下 sql 命令
DECLARE @cols NVARCHAR (MAX)
SELECT @cols = COALESCE (@cols + ',['+ cast(Month as nvarchar(2))+']' , '['+ Cast(Month as nvarchar(2))+']')
FROM (select distinct Month from Employee WHERE Year*100+Month BETWEEN 201704 and 201712 ) as e
PRINT @cols
结果是
[9],[12],[6],[7],[10],[4],[5],[11],[8]
但我真的希望它按排序顺序排列
[4],[5],[6],[7],[8],[9],[10],[11],[12]
变量合并 is documented as being non-deterministic, and may cause incorrect results,特别是在存在 ORDER BY
的情况下。您也不能将 ORDER BY
放在派生的 table 或视图中,原因很明显:最终排序 仅 由外部查询确定。
您应该改为只使用 STRING_AGG
进行聚合。您可以使用 WITHIN GROUP (ORDER BY
来获取顺序。
另请注意:
- 始终使用
QUOTENAME
将列名括起来,而不是自己动手,因为转义可能很复杂。 - 最好对列进行精确比较,而不是对它们进行计算然后比较,因为这样您就可以命中索引(sarge-ability)。
- 最好将日期存储在实际的日期列中,而不是乱用多个列,但我会将数据库重新设计留给您
DECLARE @cols NVARCHAR(MAX) = (
SELECT STRING_AGG(QUOTENAME(Month), N',') WITHIN GROUP (ORDER BY Month)
FROM (
select distinct
Month
from Employee
WHERE Year = 2017
AND Month BETWEEN 4 AND 12
) as e
);
对于 SQL Server 2016 及更早版本,您可以使用旧的 FOR XML
方法:
DECLARE @cols NVARCHAR(MAX) = STUFF((
SELECT N',' + QUOTENAME(Month)
FROM (
select distinct
Month
from Employee
WHERE Year = 2017
AND Month BETWEEN 4 AND 12
) as e
ORDER BY Month
FOR XML PATH(''), TYPE
).value('text()[1]','nvarchar(max)')
, 1, LEN(N','), N'');