Question

By happenstance, I noticed that the results from a query on one of my tables in a SQL Server database is doing something unexpected, and I'm not sure why.

For brevity, I'm removing some of the fields from the query and including only the sort criteria. Consider the two queries in the code below:

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

and

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

The primary difference between them being, one returns the entire contents of the "History" table sorted by date, the other the quantity set by the user. The History table, by default, is sorted by Serial Number ascending, and Serial Number is type nvarchar.

Looking at the results, I noticed the 2nd query is returning a set of slightly out of order data: enter image description here

Why is this? The rest of the rows are sorted correctly, and the first query appears to work as intended, flipping the rows circled in the picture. Is the SQL Server sort filter doing something different than the BindingSource?

I even noticed that when I append WHERE [Actual Ship Date] = '08/01/2013' to the 2nd query, it places the rows in the correct order. Can anyone shed some light on this? The results aren't wrong by much, but they're still wrong in the context of my program.

Was it helpful?

Solution

The 'ORDER BY' clause is the only way to absolutely guarantee order in the SQL language. However, in T-SQL you normally get things in the order of the clustered index; is that what you meant by the default sorting on the history table? This is because the actual records are stored sorted, so the easiest thing for SQL to do is just return them in the order it finds them.

Once you specify 'ORDER BY [Actual Ship Date]', you're telling SQL Server that it only has to sort by that field, and it can ignore Serial Number. So it sorts on ship date, and then returns 100 records from an internal, sorted but temporary set of records. So it's no longer reading straight through the clustered index, and you lose the property of being sorted by Serial Number.

If you want both, add 'ORDER BY [Actual Ship Date] ASC, [Serial Number] [DESC]'.

For a bit of background reading, have a read about stable and unstable sorts. The tl;dr is that some sort algorithms will jumble up any existing order in a list when you sort by a different criteria. In your example, an already-sorted list (sorted by serial number) is jumbled WRT to the serial number because it's being sorted only by the ship date. SQL's 'ORDER BY' is an example of an unstable sort, which is why your serial numbers are jumbled.

OTHER TIPS

The comment should get credit for the answer but they did not post an answer.
If Servy posts an answer then give him the check mark.
Same date so neither is wrong.
Add Serial Number to the sort.

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

In absence of a sort no order is guaranteed.
If you need consistent sorting then include the PK as part of the sort.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top