C# SQL用户定义的值的聚合顺序是否保留?
Im使用中的代码创建用户定义的聚合,以将字符串与SQL server中的C# SQL用户定义的值的聚合顺序是否保留?,c#,sql,sql-server-2008,clr,user-defined-aggregate,C#,Sql,Sql Server 2008,Clr,User Defined Aggregate,Im使用中的代码创建用户定义的聚合,以将字符串与SQL server中的groupby的连接起来。我的要求之一是连接值的顺序与查询中的顺序相同。例如: 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
groupby的
连接起来。我的要求之一是连接值的顺序与查询中的顺序相同。例如:
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
结果似乎总是正确的,正如预期的那样,但我遇到的情况是,顺序不保证,并且属性SqlUserDefinedAggregateAttribute.IsInvariantToOrder
仅保留供将来使用
所以我的问题是:假设字符串中的串联值可以以任何顺序结束,这是正确的吗
如果是这种情况,那么为什么MSDN页面上的示例代码使用了
IsInvariantToOrder
属性?我怀疑这里的一个大问题是您的语句“与查询中的语句相同”-但是,您的查询从未定义(并且无法定义)通过聚合的内容的顺序(当然,您可以通过在分组依据
之后添加排序依据
)对分组进行排序。除此之外,我只能说它完全基于一个集合(而不是一个有序序列),从技术上讲,顺序确实是未定义的。虽然公认的答案是正确的,但我想分享一个其他人可能会发现有用的解决方法。警告:这涉及到根本不使用用户定义的聚合:)
下面的链接介绍了一种只使用SELECT语句和varchar变量构建串联分隔列表的优雅方法。(对于该线程)的好处是,您可以指定行的处理顺序。缺点是,如果不进行痛苦的迭代,就无法轻松地跨多个不同的行子集连接
不完美,但对于我的用例来说是一个很好的解决方法
无法回答您的MS问题,但是
GROUP\u CONCAT
允许您确定连接。@kerrek-注意,这是标记为SQL Server
而不是MySQL
的SQL Server中恐怕没有GROUP\u CONCAT
2008@JNK:哦,这不是标准的SQL吗?那样的话没关系!如果您的顺序完全依赖于连接的值,则可以管理C#代码中的顺序。我不是C#coder,但对它做了一些修改,因此它在stringbuilder
上使用insert而不是append生成了相反的顺序。我想您可以在Terminate()中对字符串进行排序
返回之前。+1-搜索SQL Order
等等,你会得到很多关于类似问题的帖子。如果你有top
语句的内部select,而不是group by,你可以指定Order by
。@Marc我用一个使用top
的内部select的查询更新了我的问题语句和排序依据。使用group by和Concat
的最终结果是否仍然有未定义的顺序?@Magnus-内部order by
为TOP
提供了一个合理的定义。无论如何,它都不能保证任何外部操作对行的操作顺序。事实上,人们过去常常使用TOP 100%
和ORDER BY
来“排序”视图,但是优化器变得聪明起来,意识到如果需要100%的行,它不需要执行排序。如果内部查询还没有进行相同的优化,那么在SQL Server的下一个版本中可能会进行。如果他们在下一个版本中实现该“优化”,可能他们也会实现IsInvariantToOrder
来修复它。虽然这不能与我的问题中的group by一起使用。是的,没错,这就是我想说的“缺点是……”在这种情况下,你会如何指定订单?如果这是在视图或函数中,则仍然无法指定顺序,从而使其无效。若要指定处理分隔列表行的顺序,请执行以下操作:DECLARE@listStr VARCHAR(MAX)SELECT@listStr=COALESCE(@listStr+',','')+Name FROM Production.Product order BY Name--或其他任何操作
。您是正确的,这涉及到使用过程代码(变量声明),这意味着它不能在视图或函数中使用。但是它可以在SP中使用。我认为这种解决方法并非“无用”,因为它与您的具体情况无关。@MikeMonteiro这里的问题是ORDER BY
子句,而不是变量声明,这在标量函数中是可以的。我之所以说这是无用的,是因为没有办法在子查询、函数或视图中使用它,除非跳过对结果的排序,这是问题的关键所在。我从来没有想过要把它用于存储过程。