2008年08月06日

MySQLで行番号

MySQLで行番号を表示したいとき。OracleにはROW_NUMBERってのがあるので、似たような機能がないか探したところ面白い方法を見つけた。

良く紹介されているのは、ユーザー変数を利用して、

set @i:=0;
select @i:=@i+1 as rownum,user_id from user;

という感じで、2つSQLを発行するパターン。

これを1つのSQLで行う方法があった。

select @i:=@i+1 as rownum,user_id from (select @i:=0) as dummy,user;

サブクエリでユーザー変数を初期化している。
こんな発想はなかったなぁ。素晴らしい。

これでそれっぽく行番号を取得できるのだが、

MySQLのサイトの8.4. ユーザによって定義された変数にて、以下の内容があった。

ユーザ変数の評価順序は定義されておらず、与えられたクエリ内の要素に基づいて変更されることがあります。SELECT @a, @a := @a+1 ...では、MySQLは@aを先に評価し次に割り当てが実行されるように見えますが、クエリの変更(例えばGROUP BY、HAVINGまたはORDER BY節による変更)は評価順序を変更する可能性があります。

よって、order byした場合は意図しない結果になるかもしれないので要注意。

あと、似たような機能で、順位を取得する場合のSQLも見つけたので、記録。これは単純な行番号ではなくて、順位形式なので、同順位の場合もある。ただ、自己結合で直積してて、データ数が多い場合は、非常に遅いのが難点だ。

SELECT
  s0.sale_code,
  s0.sale_cgcode,
  s0.sale_cgsubcode,
  s0.sale_cnt,
  count(s1.sale_code) + 1 as sale_rank
FROM
  sale_tbl s0 LEFT OUTER JOIN sale_tbl s1 ON
  s0.sale_cnt < s1.sale_cnt
GROUP BY
  s0.sale_code,
  s0.sale_cgcode,
  s0.sale_cnt
ORDER BY
  sale_cnt desc

posted by hana at 23:23| Comment(0) | TrackBack(0) | DB,SQL関連 | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。

この記事へのトラックバック