2015-09-27 47 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