1

偶然にも、SQL Server データベース内のテーブルの 1 つに対するクエリの結果が予期しないことをしていることに気付きましたが、その理由はわかりません。

簡潔にするために、クエリからいくつかのフィールドを削除し、並べ替え基準のみを含めます。以下のコードの 2 つのクエリについて考えてみましょう。

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");

それらの主な違いは、1 つは日付でソートされた「履歴」テーブルの内容全体を返し、もう 1 つはユーザーが設定した数量を返すことです。既定では、履歴テーブルはシリアル番号の昇順で並べ替えられ、シリアル番号は nvarchar 型です。

結果を見ると、2 番目のクエリが少し順不同のデータのセットを返していることに気付きました。 ここに画像の説明を入力

どうしてこれなの?残りの行は正しく並べ替えられており、最初のクエリは意図したとおりに機能しているように見え、図の丸で囲まれた行が反転しています。SQL Server の並べ替えフィルターは、BindingSource.

WHERE [Actual Ship Date] = '08/01/2013'2 番目のクエリに追加すると、行が正しい順序で配置されることに気付きました。誰でもこれに光を当てることができますか?結果はそれほど間違っいませんが、私のプログラムのコンテキストではまだ間違っています。

4

2 に答える 2

0

'ORDER BY' 句は、SQL 言語で順序を完全に保証する唯一の方法です。ただし、T-SQL では通常、クラスター化インデックスの順序で取得します。履歴テーブルのデフォルトの並べ替えの意味は何ですか? これは、実際のレコードがソートされて格納されるためです。そのため、SQL で最も簡単に実行できるのは、見つかった順序でレコードを返すことです。

「ORDER BY [実際の出荷日]」を指定すると、そのフィールドで並べ替えるだけで済み、シリアル番号を無視できることを SQL Server に伝えます。そのため、出荷日で並べ替えてから、内部の並べ替え済みの一時的なレコード セットから 100 レコードを返します。そのため、クラスター化されたインデックスを直接読み取ることはなくなり、シリアル番号で並べ替えるというプロパティが失われます。

両方が必要な場合は、「ORDER BY [実際の出荷日] ASC、[シリアル番号] [DESC]」を追加してください。

少し背景を読むには、安定および不安定なソートについて読んでください。tl;dr は、別の基準で並べ替えると、一部の並べ替えアルゴリズムがリスト内の既存の順序をごちゃ混ぜにすることです。あなたの例では、出荷日のみでソートされているため、既にソートされたリスト (シリアル番号でソート) が WRT でシリアル番号に乱雑になります。SQL の 'ORDER BY' は不安定な並べ替えの例です。これがシリアル番号がごちゃ混ぜになる理由です。

于 2013-08-05T16:56:38.527 に答える