2013-08-05 57 views
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。在結果

看,我注意到了第2個查詢將返回一組略高出訂單數據: enter image description here

這是爲什麼?其餘的行正確排序,並且第一個查詢似乎按預期工作,翻轉圖片中圈出的行。 SQL Server排序篩選器是否執行與BindingSource不同的操作?

我甚至注意到,當我將WHERE [Actual Ship Date] = '08/01/2013'附加到第二個查詢時,它將按照正確的順序放置行。任何人都可以對此有所瞭解嗎?結果並沒有錯誤多得多,但他們仍然是我的程序中的錯誤。

+4

*歷史記錄表默認情況下按序號排序*這是錯誤的沒有RDMS使用SQL語句保證行順序沒有順序by –

+4

您訂購它們的日期都是一樣的,所以排序是*不*錯*。如果您希望通過日期和其他字段對它們進行排序,請將它放在您的查詢中,而不是期望它讀取您的想法並隱式使用您想要的第二列。它可能恰好選擇有時將數據返回到您想要的數據附近是無關緊要的。如果您希望數據庫確保它在該字段上排序,請告訴它在該字段上排序。 – Servy

+0

@Servy如果史蒂夫庫珀回答的是真實的,那麼數據庫返回的內容有一些明確的,並且有一定的順序。我的查詢可能不完整,但是我基於觀察到的行爲構建它們。但是,謝謝你,這就是爲什麼我發佈這個問題,並堅持下去,以瞭解我不知道的事情:] –

回答

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 and unstable sorts。 tl; dr是,當你按不同的標準排序時,某些排序算法會混淆列表中的任何現有順序。在您的示例中,已排序的列表(按序列號排序)將WRT混淆爲序列號,因爲它在發貨日期僅排序了。 SQL的'ORDER BY'是一個不穩定排序的例子,這就是你的序列號混亂的原因。

+0

感謝您的解釋。這正是我所問的。幾乎每次(直到現在)我以任何方式訪問表中的記錄,它總是按主鍵排序,所以我只是假設這是我得到的。 –

+0

很高興我能幫忙! –

0

該評論應該得到相應的答案,但他們沒有發佈答案。
如果Servy發佈答案,然後給他複選標記。
同一天所以沒有錯。
將序列號添加到排序中。

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

在沒有排序的情況下,沒有訂單保證。
如果您需要一致的排序,請將PK作爲排序的一部分。