查询结果排序与预期不同

时间:2013-08-05 16:35:51

标签: c# .net sql-server sorting bindingsource

通过偶然的情况,我注意到SQL Server数据库中某个表的查询结果是意外的,我不知道为什么。

为简洁起见,我将从查询中删除一些字段,仅包括排序条件。考虑以下代码中的两个查询:

bindingSource_History.DataSource = AsTable("SELECT [Serial Number], [Actual Ship Date] FROM dbo.History");
bindingSource_History.Sort = "Actual Ship Date DESC";

bindingSource_History.DataSource = AsTable("SELECT TOP 100 [Serial Number], [Actual Ship Date] FROM dbo.History ORDER BY [Actual Ship Date] DESC");

它们之间的主要区别在于,一个返回按日期排序的“历史”表的全部内容,另一个返回用户设置的数量。默认情况下,History表按序列号升序排序,序列号的类型为nvarchar。

查看结果,我注意到第二个查询返回了一组稍微乱序的数据: enter image description here

这是为什么?其余行正确排序,第一个查询似乎按预期工作,翻转图片中圈出的行。 SQL Server排序过滤器是否执行与BindingSource不同的操作?

我甚至注意到,当我将WHERE [Actual Ship Date] = '08/01/2013'附加到第二个查询时,它会按正确的顺序放置行。任何人都可以对此有所了解吗?结果并没有错误很多,但在我的程序环境中它们仍然是错误的。

2 个答案:

答案 0 :(得分:0)

评论应该得到答案,但他们没有发布答案 如果Servy发布了答案,那么给他一个复选标记 同一天,所以都没有错 添加序列号到排序。

SELECT TOP 100 [Serial Number], [Actual Ship Date] 
FROM dbo.History 
ORDER BY [Actual Ship Date] DESC, [Serial Number] asc

如果没有排序,则不保证订单 如果您需要一致的排序,请将PK作为排序的一部分。

答案 1 :(得分:0)

'ORDER BY'子句是绝对保证SQL语言顺序的唯一方法。但是,在T-SQL中,您通常会按聚簇索引的顺序获取内容;你在历史表上的默认排序是什么意思?这是因为实际记录是按存储顺序存储的,因此SQL最简单的方法就是按照它们找到的顺序返回它们。

指定'ORDER BY [实际发货日期]后,您告诉SQL Server 必须按该字段排序,并且它可以忽略序列号。因此它在发货日期排序,然后从内部的,已排序但临时的记录集中返回100条记录。因此,它不再直接读取聚簇索引,并且您将失去按序列号排序的属性。

如果您想要两者,请添加'ORDER BY [实际发货日期] ASC,[序列号] [DESC]'。

对于一些背景阅读,请阅读stable and unstable sorts。 tl; dr是当你按照不同的标准排序时,某些排序算法会混淆列表中的任何现有订单。在您的示例中,已排序的列表(按序列号排序)与序列号混杂,因为它在发货日期之前仅按排序。 SQL的'ORDER BY'是一个不稳定排序的例子,这就是你的序列号混乱的原因。