TOP句を用いる際にはORDER BY句の内容による抽出レコード数の違いに注意

 TOP句はそれほど多用されるものではありませんがが、いざ使ってみたときに指定したレコード数と実際に抽出されるレコード数が違っていて混乱することがあります。その理由はORDER BY句の有無とその内容によるものですので、ここではその実例を見てみます。

f:id:accs2014:20180128103931p:plain:right:w150

 まず、このような数字が並んだだけの単純なテーブルを用います。


f:id:accs2014:20180128103928p:plain:right:w250

 クエリのSQLビューで次のように記入します。



SELECT TOP 3 数字テーブル.数字
FROM 数字テーブル;


f:id:accs2014:20180128103921p:plain:right:w150

 データシートビューを見てみるとこのようになります。 
 3つのレコードが抽出されているのは指定どおりですが、抽出されるのは(TOPという言葉のせいで間違いやすいですが)値が大きいものとか小さいものというわけではないことに注意が必要です。また、この例ではテーブルの先頭から3つ抽出したように見えますが、必ずしもそうなるという保証はありません。ORDER BY句を伴わない限り、TOP句がどのレコードが抽出されるのかについては何とも言えません。ただし、ORDER BY句がない場合、抽出されるレコード数は指定した数字そのものとなります。


f:id:accs2014:20180128103919p:plain:right:w250

 では、このようなSQLではどうなるでしょうか。
 レコードを数字の昇順で並べ替えているので「8」が3つ抽出されそうに思えますが…



SELECT TOP 3 数字テーブル.数字
FROM 数字テーブル
ORDER BY 数字テーブル.数字;


f:id:accs2014:20180128103916p:plain:right:w150

 実際は5つ抽出されます。
 ORDER BY句により並べ替えた場合、同順となるレコードはすべて抽出されるので、このような場合は指定したレコード数より多くのレコードが抽出されます。


f:id:accs2014:20180128104003p:plain:right:w400

 次に、このようなテーブルを用いてみます。


f:id:accs2014:20180128104000p:plain:right:w300

 SQLの画面は省略しますが、次のようなSQLを実行した結果です。
 テーブルの先頭にある3つのレコードが抽出されていますが、やはりORDER BYを伴っていないため、どのレコードが抽出されるかについての保証はありません。



SELECT TOP 3 選手ID, 選手名, 得点
FROM 成績テーブル;


f:id:accs2014:20180128103958p:plain:right:w300

 次のようなSQLの実行結果です。
 ORDER BYを伴っていますが、得点のみによる昇順としているため、得点が下から2位(タイ)である3つのレコードがすべて抽出されています。結果的に4レコードが抽出されています。



SELECT TOP 3 成績テーブル.選手ID, 成績テーブル.選手名, 成績テーブル.得点
FROM 成績テーブル
ORDER BY 成績テーブル.得点;


f:id:accs2014:20180128103955p:plain:right:w300

 次のSQLの実行結果です。
 上記とほとんど同じですが、得点と選手IDによる昇順となっているので同順位となる選手はおらず、レコードは3つだけ抽出されています。



SELECT TOP 3 成績テーブル.選手ID, 成績テーブル.選手名, 成績テーブル.得点
FROM 成績テーブル
ORDER BY 成績テーブル.得点, 成績テーブル.選手ID;


f:id:accs2014:20180128114004p:plain:right:w150

 最後に、次のSQLの実行結果です。
 抽出される値(得点)が全く同じとなる場合でも、ORDER BYによる順位付けで差が付く(同順にならない)のであれば、レコードは指定された数だけ抽出されます。



SELECT TOP 3 成績テーブル.得点
FROM 成績テーブル
ORDER BY 成績テーブル.得点, 成績テーブル.選手ID;


 まとめますと次のようになります。

  • ORDER BYがなければ確実に指定した件数が抽出される(ただしどのレコードが選ばれるかは何とも言えない)
  • ORDER BYがある場合はその内容に基づき順位をつけ、結果的に指定した件数以上の件数が抽出されることがある(同順位になるものがある場合)