2015-09-27 50 views
1

我有一些非常奇怪的行为与coalesce。当我不指定返回量(TOP 50)我只得到一个最后的结果,但如果我删除“排序”它工作...下面的例子使用订单时COALESCE的奇怪的TSQL行为通过

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

只返回一个最后的结果:

湿婆碗

,但如果我specifiy一个最大的回报量(只增加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 

我得到的所有结果以正确的顺序

草案中弹跳测试,周日在如心的,先生。 McGibblets,平常的赌注,湿婆碗

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

任何洞察什么可能导致此?我真的不想设置限制,但它是目前返回的所有数据的唯一途径...感谢

+0

这是未注释的黑客,你不应该那样做。有一些标准的方法可以用xml来做到这一点。 –

+0

这就是我们为'XML Path()'将行连接成单个字符串的原因 –

+0

[Demo](http://sqlfiddle.com/#!6/76d79/2/0) – lad2025

回答

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代替连接。

+0

SQLFiddleDemo不应该工作!这正是我遇到这个问题,但它在那里工作... – bfritz

+0

@bfritz我的SQL小提琴有不同的结构/统计/索引等。但这是一个非常好的例子,它依赖于内部表示和执行计划 – lad2025

+0

我可能只需要坚持TOP(50)hack来强制执行,我已经在其他几个地方使用了相同的方法,并且作为我的服务每天处理超过8000万个请求,我试图摆脱由于服务器负载而带来大量嵌套选择等的解决方案。我只需要构建一个字符串(使用单个select查询)并将其返回FAST! – bfritz