1

碰巧,我注意到对 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");

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

查看结果,我注意到第二个查询返回了一组稍微乱序的数据: 在此处输入图像描述

为什么是这样?其余行已正确排序,第一个查询似乎按预期工作,翻转图片中圈出的行。SQL Server 排序筛选器的作用与BindingSource?

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

4

2 回答 2

0

评论应该得到答案,但他们没有发布答案。
如果 Servy 发布答案,则给他打勾。
相同的日期,所以两者都没有错。
将序列号添加到排序中。

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

在没有排序的情况下,不能保证顺序。
如果您需要一致的排序,则将 PK 作为排序的一部分。

于 2013-08-05T16:56:24.120 回答
0

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

一旦您指定了“ORDER BY [Actual Ship Date]”,您就是在告诉 SQL Server 它只需要按该字段排序,并且可以忽略序列号。因此,它按发货日期排序,然后从内部已排序但临时的记录集中返回 100 条记录。所以它不再直接读取聚集索引,并且您失去了按序列号排序的属性。

如果两者都需要,请添加“ORDER BY [Actual Ship Date] ASC, [Serial Number] [DESC]”。

如需了解一些背景知识,请阅读有关stable 和 stable sorts的内容。tl;dr 是,当您按照不同的标准进行排序时,某些排序算法会混淆列表中的任何现有顺序。在您的示例中,已经排序的列表(按序列号排序)与序列号混杂在一起,因为它按发货日期排序。SQL 的“ORDER BY”是一个不稳定排序的例子,这就是为什么你的序列号是混乱的。

于 2013-08-05T16:56:38.527 回答