2011-07-06 23 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

你会怎么在这种情况下指定一个订单?如果这是在一个视图或函数内部,指定一个订单仍然是不可能的,这使得它无用。 –

相关问题