我目前正忙着使用AdventureWorks示例数据库和LinqPad来解决一些想法。
这是有问题的查询:
SalesOrderHeaders.GroupBy (soh => new {soh.CustomerID, soh.BillToAddressID})
.Where(soh => soh.Skip(1).Any())
.Dump();
想法是根据某些标准找到重复项,然后显示除第一组数据之外的重复项。结果应从表格中删除。
执行查询后我得到结果A)
再次执行查询后,我得到结果B)
我不关心查询的正确结果,而是关于结果集的排序。只存在这两种可能性,并且它们在查询的每次运行中都是交替的。 当然我可以按Key订购,但我更感兴趣的是为什么会发生这种情况呢?为什么订单是chaning / alternate?
答案 0 :(得分:6)
sql server select query的结果集顺序不确定。它只是sql server的工作原理,它不是linq或linqpad中的错误。正如您自己指出的那样,在查询中获得确定性结果的唯一方法是使用OrderBy
子句。
编辑:如果多次运行查询,关于在SSMS中获得相同的结果,请参阅this。这篇文章解释了为什么如果多次执行查询以及为什么不应该依赖它,可能会得到相同的结果。
答案 1 :(得分:1)
如前所述,排序绝不是确定性的,但是在sql查询或Linq查询中尝试并插入orderby子句,这是使其成为确定性的唯一方法。
事实上,让我们在数据库中看得更深一些。 DB将通过i / o从磁盘获取所有数据。数据存储在内部sql server结构中,如页面,扩展区,段(这些是Oracle数据块,我希望sql server有类似的东西)。现在,当触发查询时,数据库将知道从中获取数据的所有不同位置,但这不是串行操作,而是一种并行获取,然后组合不同的数据集以提供用户视图。现在正如我们所知道的那样,对于线程来说,永远不能确定谁先行,谁首先返回,这完全是线程的OS调度,希望进一步澄清。
OrderBy子句将处理以特定顺序生成的获取数据,因此将始终产生确定性结果。