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