2011-07-06 22 views
11

Im使用this MSDN page中的代碼創建一個用戶定義的聚合,以在SQL Server中連接字符串與group by's。我的要求之一是連接值的順序與查詢中的順序相同。例如:保存SQL用戶定義的集合值順序?

Value Group 
1  1 
2  1 
3  2 
4  2 

使用查詢

SELECT 
    dbo.Concat(tbl.Value) As Concat, 
    tbl.Group 
FROM 
    (SELECT TOP 1000 
    tblTest.* 
    FROM 
    tblTest 
    ORDER BY 
    tblTest.Value) As tbl 
GROUP BY 
    tbl.Group 

會導致:

Concat Group 
"1,2" 1 
"3,4" 2 

結果似乎總是正確的,具有符合市場預期,但比我碰到this page來,指出該訂單不能得到保證,並且該屬性SqlUserDefinedAggregateAttribute.IsInvariantToOrder僅供將來使用。

所以我的問題是:是否正確假設字符串中的連接值可以以任何順序結束?
如果是這種情況,那麼爲什麼MSDN頁面上的示例代碼使用IsInvariantToOrder屬性?

+0

不能回答你的MS的問題,但'GROUP_CONCAT'讓你成爲確定性有關的連接。 –

+0

@kerrek - 注意這個標籤爲'SQL Server'不是'MySQL' – JNK

+0

恐怕SQL Server 2008中沒有'GROUP_CONCAT' – Magnus

回答

5

我懷疑這裏的一個大問題是你的聲明「等同於查詢」 - 然而,你的查詢從未定義(而不能定義)由事物的順序進行聚合(你當然可以秩序,通過在GROUP BY之後具有ORDER BY)。除此之外,我只能說它完全基於集合(而不是有序序列),並且技術上的順序確實是未定義的。

+0

+1 - 在SO上搜索'SQL Order',你會得到很多關於類似問題的文章。 – JNK

+0

你可以指定'order by',如果你有一個內部選擇的「頂部」聲明,並且在這個聲明之上。 – Magnus

+0

@Marc我已經更新了我的問題,使用帶有'top'語句和'order by'的內部選擇的查詢。使用group by和'Concat'的最終結果是否仍然有一個未定義的順序? – Magnus

1

雖然接受的答案是正確的,但我想分享其他人可能會覺得有用的解決方法。警告:它涉及到根本不使用用戶定義的聚合:)

下面的鏈接描述了一種優雅的方式,只使用SELECT語句和varchar變量來構建連接的分隔列表。好處在於,您可以指定處理行的順序。缺點是你不能輕鬆地在許多不同的行子集上進行連接而不會產生痛苦的迭代。

不完美,但對我的用例來說是一個很好的解決方法。

http://blog.sqlauthority.com/2008/06/04/sql-server-create-a-comma-delimited-list-using-select-clause-from-table-column/

+0

雖然這不能像我的問題一樣用於組。 – Magnus

+0

是的,正是 - 那正是我想通過說「缺點是...」 –

+0

你會怎麼在這種情況下指定一個訂單?如果這是在一個視圖或函數內部,指定一個訂單仍然是不可能的,這使得它無用。 –

相關問題