使用Order By时使用COALESCE的奇怪TSQL行为

时间:2015-09-27 09:33:19

标签: tsql sql-server-2012 sql-order-by coalesce

我有一些非常奇怪的合并行为。当我没有指定退货金额(TOP(50))时,我只得到一个最后的结果,但是如果我删除“Order By”它就有效......下面的例子

DECLARE @result varchar(MAX)
SELECT @result = COALESCE(@result + ',', '') + [Title]
FROM Episodes WHERE [SeriesID] = '1480684' AND [Season] = '1' Order by [Episode] ASC
SELECT @result

只返回最后一个结果:

  

湿婆碗

但如果我指定最大回报金额(仅将 TOP(50)添加到同一报表中)

DECLARE @result varchar(MAX)
SELECT TOP(50) @result = COALESCE(@result + ',', '') + [Title]
FROM Episodes WHERE [SeriesID] = '1480684' AND [Season] = '1' Order by [Episode] ASC
SELECT @result

我按正确顺序得到所有结果

  

选秀,弹跳测试,周日在Ruxin,Mr。 McGibblets,通常的赌注,湿婆碗

罪魁祸首似乎是[Title]列,好像我返回了一个不同的列,似乎没有指定返回限制。 FYI [Title]是VARCHAR(MAX)NOT NULL列。

有什么可能导致这种情况的见解?我真的不想设置限制,但它是目前返回所有数据的唯一方式...谢谢

1 个答案:

答案 0 :(得分:2)

你不能依赖连接:

SELECT @result = COALESCE(@result + ',', '') + [Title]
FROM Episodes
...

Execution Plan and Results of Aggregate Concatenation Queries Depend Upon Expression Location

依赖于CTE /临时表/执行计划的示例将得到不同的结果:

<强> SqlFiddleDemo

DECLARE @text VARCHAR(MAX) = ''
       ,@text2 VARCHAR(MAX) = '';

SELECT CAST(ROW_NUMBER() OVER (ORDER BY name) AS INT) AS number 
INTO #numbers 
FROM master..spt_values 


;WITH numbers (number)
AS
(
    SELECT CAST(ROW_NUMBER() OVER (ORDER BY name) AS INT) AS number
    FROM master..spt_values 
),a AS
(
    SELECT number FROM numbers WHERE number < 10
)
SELECT      @text = @text + LTRIM(STR(a.number))
FROM        a
ORDER BY    a.number DESC


;WITH numbers (number)
AS
(
    SELECT number FROM #numbers
),
a
AS
(
    SELECT number FROM numbers WHERE number < 10
)
SELECT      @text2 = @text2 + LTRIM(STR(a.number))
FROM        a
ORDER BY    a.number DESC

SELECT @text, @text2;

我制作了示例,您的第一个查询正在运行SqlFiddleDemo。但是您的解决方案高度依赖于执行计划。

使用 XML + STUFF 代替连接。