TOP 句の紹介

TOP 句の紹介です。
TOP (Transact-SQL)
SQL Server 2000 でもありましたが、2005 から構文が変わり機能が強化されています!

2000 では、TOP だったのが、2005 からは、 TOP () となっています。
括弧で囲むことで、数値だけでは無く式も書けるようになりました。
これにより、TOP 句に変数を渡すことも出来ますし、サブクエリも書けます。

下位互換性のために、SELECT では、括弧無しでも動作します。括弧無しの場合は、数値だけしか指定出来ません。
このせいで、エラーが出るため数値しかダメなのかと思っていた人も多いはず…。
TOP 句でもパラメータが使えます - お だ のスペース

サブクエリを使った例は、以前書いているのでそちらを
テーブルの行を N 件に増やしたい場合 - お だ のスペース

ここでは PERCENT と WITH TIES について紹介します。

use [テスト]
create table [台帳] ( 
  [名前] nvarchar(10) not null, 
  [金額] int not null
)
insert into [台帳] values ('田中 さん', 3000)
insert into [台帳] values ('鈴木 さん', 2000)
insert into [台帳] values ('伊藤 さん', 5000)
insert into [台帳] values ('佐藤 さん', 2000)
insert into [台帳] values ('高橋 さん', 7000)
insert into [台帳] values ('渡辺 さん', 6000)
insert into [台帳] values ('中村 さん', 5000)
insert into [台帳] values ('山本 さん', 1000)
insert into [台帳] values ('小林 さん', 2000)
select * from [台帳] order by [金額]


テーブルを作成して、テストデータを準備します。

PERCENT は割合指定になります。

select top (30) percent * from [台帳] order by [金額]


10件中の30%なので、3件表示されます。
金額が 2000 のデータで表示されていないものがあります。最終行と同じ値になっている行を表示するには WITH TIES を指定します。

select top (30) with ties  percent * from [台帳] order by [金額]


割合指定した際に、行数が小数値になった場合はどうなるでしょうか?

TOP (Transact-SQL) より抜粋

PERCENT
クエリの結果セットの先頭から、expression で指定したパーセントの行のみを返すよう指定します。小数値は整数値に切り上げられます。 

と書かれており切り上げられる様です。
試してみましょう。

-- 結果行数が小数になるときは、は切り上げ
select top (1) percent * from [台帳] order by [金額]
select top (13) percent * from [台帳] order by [金額]


10 件の 1% は 0.1行ですが切り上げて 1行、13% は 1.3行ですが、切り上げて 2行出力されています。
違う値で試してみると…

-- 小数になるのに、切り上げられない…
select top (11) percent * from [台帳] order by [金額]
select top (22) percent * from [台帳] order by [金額]


理由はわかりませんが、何故か切り上がってくれません。。*1


2005 以降では、式も書けるようになって便利になっている TOP 句、括弧で囲んで使いましょう!


クエリ全文

use [テスト]
create table [台帳] ( 
  [名前] nvarchar(10) not null, 
  [金額] int not null
)
insert into [台帳] values ('田中 さん', 3000)
insert into [台帳] values ('鈴木 さん', 2000)
insert into [台帳] values ('伊藤 さん', 5000)
insert into [台帳] values ('佐藤 さん', 2000)
insert into [台帳] values ('高橋 さん', 7000)
insert into [台帳] values ('渡辺 さん', 6000)
insert into [台帳] values ('中村 さん', 5000)
insert into [台帳] values ('山本 さん', 1000)
insert into [台帳] values ('小林 さん', 2000)
select * from [台帳] order by [金額]
-- 割合指定
select top (30) percent * from [台帳] order by [金額]
select top (30) percent with ties * from [台帳] order by [金額]
-- 結果行数が小数になるときは、は切り上げ
select top (1) percent * from [台帳] order by [金額]
select top (13) percent * from [台帳] order by [金額]
-- 小数になるのに、切り上げられない…
select top (11) percent * from [台帳] order by [金額]
select top (22) percent * from [台帳] order by [金額]
go
drop table [台帳]

*1:今後判明したら紹介します。