tech.guitarrapc.cóm

Technical updates

Sybase SQL AnywhereでMySQLのLIMIT句のようにクエリが返すRAW数を制限したい

Sybase SQL Anywhere使ってますか? MySQLを使っていて便利!!とよく言われるのがLIMIT句です。 MySQLでは、LIMIT句を使うことでクエリが返すRAW数(行数)を明示的に制限できます。

例えば、従業員テーブル(emp_def)から初めのレコードだけ取ってくるなら以下のようになります。

SELECT
	*
FROM
	emp_def
ORDER BY
	id
LIMIT 1 ;

あるいは、6,7,8,9,10番目のレコードを取ってくるなら以下ですね。

SELECT
	*
FROM
	emp_def
ORDER BY
	id
LIMIT 5, 5 ;

では、Sybase SQL Anywhereで同じ動作させることはできないのか。 もちろん、できます。 ====

Sybase SQL Anywhere における取得RAWの制限方法

Sybase SQL  Anywehre 9と11での例です。(12でも使えたかと) やり方としては、以下の3つが考えられます。

1. SELECT句にFIRSTキーワードを使う
2. SELECT句にTOPキーワードを使う
3. SQL発行時にROWCOUNT設定を指示する

1. SELECT句にFIRSTキーワードを使う

SELECT句の中に、FIRSTキーワードを埋め込むことで、クエリが返すRAW数を始めの1RAWに制限することができます。

SELECT FIRST
	*
FROM
	emp_def
ORDER BY
	id ;

2. SELECT句にTOPキーワードを使う

LIMITとまさに同じような使い方ができるのが、TOPキーワードです。

SELECTの後にTOPキーワードを置いて取得するRAW数の指示をするだけで、クエリが返すRAW数を制限できます。

使い方は簡単、TOP row_number(取得RAW数)だけです。

SELECT TOP 1
	*
FROM
	emp_def
ORDER BY
	id ;

もちろん、MySQLのLIMIT句のように、開始位置とRAW数も制限できます。その場合、TOPキーワードとSTART ATキーワードを組み合わせます。

使い方は簡単です、TOP row_number(取得RAW数) START AT start_int(開始位置)と書くだけです。以下の例で6,7,8,9,10番目の結果RAWが返されます。

SELECT TOP 5 START AT 5
	*
FROM
	emp_def
ORDER BY
	id ;

3. SQL発行時にROWCOUNT設定を指示する

Sybase SQLには、ROWCOUNT設定があります。

Interactive SQL(dbisql)やSybase Central(scjview)をお使いの方にとっては設定パラメータで見慣れていらっしゃるあれです。

SQL実行前に、ROWCOUNT設定をSETで明示的に指示する事で、クエリが返すRAW数を制限できます。

ただし、ROWCOUNTは接続毎に保持されるため、SQL発行後はSET ROWCOUNT 0として設定した制限を外して下さい。(SET ROWCOUNT 0で制限がなくなります)

-- 始めの1RAWのみ返すように制限
SET ROWCOUNT 1;
-- クエリを実行
SELECT
	*
FROM
	emp_def
ORDER BY
	id;
-- 制限したRAW数を解除する
SET ROWCOUNT 0;

蛇足

始めのRAWではなく、最後のRAWを取得したい場合は、簡単ですね? ORDER BY  DESCとするだけです。

※ORDER BYで特にキーワード指示をしなければASCとなります。 これで、並び順(ORDER BY)が逆になった結果から、初めのRAWを取得 = 最後のRAWを取得できます。

注意1

言わずもがな…でしょうが、MySQLのLIMIT句やSybaseのFIRST、TOPキーワードを利用するときはORDER BY句で並び替え対象Columnを必ず入れましょう。

ORDER BY句がないと、どのColumnで制限するの?と、警告が帰ってきます。

※dbisql -noguiではエラーが出ずPRIMARY KEYで並びます。

※dbisqlやscjviewなど、GUI環境ではポップアップ警告が出ます。(一応出力はしますが) [エラー例]

The result returned is non-deterministic Error constant
SQLCODE	122
ODBC 3 State	01000

[警告の出るSQL例]

SELECT TOP 5 START AT 5
	*
FROM
	emp_def ;

[ORDER BYを指定することでエラーが消える]

SELECT TOP 5 START AT 5
	*
FROM
	emp_def
ORDER BY
	id ;

注意2

当然なので書かなくてもとも思うのですが、念のため。

LIMIT同様に、TOPは「クエリが返してくるレコード結果を制限して出力してる」だけです。 つまり、クエリがいったん全結果を出力した上で、表示を制限しているだけなので前結果出力とパフォーマンスは変わりません。

そのため、クエリが返すRAW数を制限してパフォーマンスを向上させたいなら、クエリをチューニングしましょう。

参考資料

  1. Sybase SQL AnywhereのSQL資料 : iAnywhere社のSQL Anywhere 12 製品マニュアル   2. The result returned is non-deterministic Error constantエラーについて : http://dcx.sybase.com/1101/en/saerrors_en11/err122.html