Webサイト制作コースのお申し込みはこちら Webサイト制作コースのお申し込みはこちら

SQLで行番号

SQLの結果セット(検索結果)に対して、1〜の連番となる行番号を振りたいシーンは多々あるでしょう。

Oracle、MySQL、PostgreSQLなど、ほとんどのRDB(リレーショナルデータベース)には、行番号を振る機能があります。

この記事では、SQLの結果セット(検索結果)に対して行番号を振る方法を解説します。

ROW_NUMBER関数

ROW_NUMBER関数はSELECT文で取得した検索結果に対し、行番号(連番)を振るための関数です。グループ毎に連番を振ったり、指定したソート条件の順に連番を振ったりできます。

ROW_NUMBERの構文

ROW_NUMBER関数の構文を確認しましょう。

ROW_NUMBER() OVER ( [ PARTITION BY [パーティションカラム], [パーティションカラム], ...] ORDER BY [ソートカラム], [ソートカラム], ... )

パーティションカラムは、結果をセットをパーティションカラム毎ごとに1~からの連番を振ります。パーティションカラムを省略した場合、結果セット全体で連番が振られます。

ソートカラムは、連番を振る順序を決めるソートカラムを指定します。ROW_NUMBER関数では、ソートカラムの指定は必須です。
パーティションカラムとソートカラムを同時に指定すると、パーティション毎に、指定したソートカラムの昇順または降順で連番が振られます。

以下は、ROW_NUMBER関数が使えるリレーショナルデータベース(RDB)のリストです。

ROW_NUMBERを使って連番を振る

では、ROW_NUMBER関数を使って、連番を振るサンプルコードを見ていきましょう。

まず最初のサンプルは、ROW_NUMBER関数で、scoresテーブルの「score」列の昇順(ASC)で連番を振るシンプルなSQLの例です。

SELECT 
  ROW_NUMBER() OVER(ORDER BY score ASC) num
, user_name
, score
FROM scores

実行結果

SQLを実行すると、次の表のように「score」の昇順で連番が振られているのが分かります。

num user_name score
1 山田 太郎 100
2 鈴木 一郎 40
3 佐藤 太郎 50
4 田中 次郎 40

次は、パーティションカラムを指定して、グループ毎に行番号の連番を振るサンプルを見ていきましょう。

次のSQLは、パーティションカラムに「city」を指定し、市区町村ごとに「score」の昇順で1~の連番を振っています。

SELECT
  ROW_NUMBER() OVER(PARTITION BY City ORDER BY Age ASC) num
  name
, city
, score
FROM scores

実行結果

num user_name city score
1 山田 太郎 Tokyo 10
2 鈴木 一郎 Tokyo 20
1 佐藤 太郎 Nagoya 30
2 田中 次郎 Nagoya 40
1 伊藤 太郎 Osaka 50

順位を付けるならRANK関数

RANK関数はSQLの結果セットに対し順位を付ける関数で、ROW_NUMBER関数と機能が似ています。

RANKROW_NUMBER関数の違いは、重複しする値に対する順位(連番)の付け方が異なります。実際にSQLを作成し、RANKROW_NUMBER関数の違いを確認していきましょう。

以下のサンプルSQLは、scoresテーブルのscore(点数)ROW_NUMBERRANKでそれぞれ降順で連番を振るSQLです。

SELECT 
  Name
, Score
, ROW_NUMBER() OVER(ORDER BY Score DESC) Rank
, ROW_NUMBER() OVER(ORDER BY Score DESC) Num
FROM scores

実行結果

user_name Score Rank NUm
山田 太郎 100 1 1
鈴木 一郎 90 2 2
佐藤 太郎 90 2 3
田中 次郎 80 4 4
伊藤 花子 80 4 5

上記の通り、Rank関数では同じ値には同じ連番順位)が割り振られ、ROW_NUMBER関数は他と重複しない連番が振られている事が分かります。

【関連記事】
【SQL】データを順位づけするRANK関数の使い方を解説

MySQLではユーザ定義変数を使って行番号を振る

MySQLではROW_NUBER関数が使えません。
「ユーザ定義変数」を使用するとで、MySQLでもROW_NUMBER関数と同等のことが行えます。

MySQLの「ユーザ定義変数」とは

「ユーザ定義変数」とは、MySQLのセッション上に定義する変数です。
同じDBセッション間で値を受け渡す時や、今回紹介するユーザ定義変数を使った連番を振る時などに使用します。

サンプルコード

次のSQLは、usersテーブルの年齢(age)の昇順に連番を振る例です。
ポイントは、@rownumを宣言している1行目や、@rownumを使った処理の部分です。

SET @rownum=0;

SELECT 
  @rownum:=@rownum+1 as num
, user_name
, score
FROM scores
ORDER BY score

実行結果

num user_name score
1 Yamada Taro 20
2 Suzuki Ichiro 30
3 Sato Taro 50
4 Tanaka Jiro 70
5 Ito Hanako 100

ROWNUM疑似列

Oracleデータベースを使用している場合、ROWNUM疑似列を使って行番号を振る事もできます。

ROWNUM疑似列は、SQLの結果セットからソート前のレコード番号を返す擬似列です。ROWNUM擬似列は、SELECT文の結果セットに暗黙的に追加され、どのSQLからでも参照できます。

ROWNUMの基本的な使い方

ROWNUM擬似列は、次のようにSELECT句にROWNUMと指定するだけで取得することができます。
次のSQLでは、usersテーブルから取得したレコードに対し、ROWNUMで行番号を取得しています。

SELECT 
  ROWNUM 
, Name
, Age
FROM users

| ROWNUM | Name          | Age  |
| ------ | ------------- | ---- |
| 1      | Yamada Taro   | 10   |
| 2      | Suzuki Ichiro | 30   |
| 3      | Sato Taro     | 20   |
| 4      | Tanaka Jiro   | 50   |
| 5      | Ito Hanako    | 40   |

ORDER BYとROWNUMを同時に使う時は注意

ROWNUMORDER BYを同時に使用すると、想定外の結果が発生するため注意が必要です。

先述したとおり、ROWNUM擬似列は「ソート前のレコード番号を表す擬似列」です。
そのため、ROWNUMで先に連番を振った後にORDER BY句によって結果のソートが行われるため、次のようなSQLを実行すると、正しく連番が取得できません。

SELECT 
  ROWNUM 
, Name
, Age
FROM users
ORDER BY Age DESC

| ROWNUM | Name          | Age  |
| ------ | ------------- | ---- |
| 4      | Tanaka Jiro   | 50   |
| 5      | Ito Hanako    | 40   |
| 2      | Suzuki Ichiro | 30   |
| 3      | Sato Taro     | 20   |
| 1      | Yamada Taro   | 10   |

上の例では、ROWNUM擬似列でまず結果セットに対して連番が振られ、その後「Age」列でソートが行われるため、ROWNUMの値が1〜の連番になりません。

さいごに

SQLで行番を振る方法について解説してきました。データのランク付けなどにも使われるROW_NUMBER関数は、色々のシステム開発で利用するため、是非覚えておきましょう。

エンジニアになりたい人に選ばれるプログラミングスクール「ポテパンキャンプ 」

ポテパンキャンプは卒業生の多くがWebエンジニアとして活躍している実践型プログラミングスクールです。 1000名以上が受講しており、その多くが上場企業、ベンチャー企業のWebエンジニアとして活躍しています。

基礎的な学習だけで満足せず、実際にプログラミングを覚えて実践で使えるレベルまで学習したいという方に人気です。 プログラミングを学習し実践で使うには様々な要素が必要です。

それがマルっと詰まっているポテパンキャンプでプログラミングを学習してみませんか?

卒業生の多くがWebエンジニアとして活躍

卒業生の多くがWeb企業で活躍しております。
実践的なカリキュラムをこなしているからこそ現場でも戦力となっております。
活躍する卒業生のインタビューもございますので是非御覧ください。

経験豊富なエンジニア陣が直接指導

実践的なカリキュラムと経験豊富なエンジニアが直接指導にあたります。
有名企業のエンジニアも多数在籍し品質高いWebアプリケーションを作れるようサポートします。

満足度高くコスパの高いプログラミングスクール「ポテパンキャンプ」

運営する株式会社ポテパンは10,000人以上のエンジニアのキャリアサポートを行ってきております。
そのノウハウを活かして実践的なカリキュラムを随時アップデートしております。

代表の宮崎もプログラミングを覚えサイトを作りポテパンを創業しました。
本気でプログラミングを身につけたいという方にコスパ良く受講していただきたいと思っておりますので、気になる方はぜひスクール詳細をのぞいてくださいませ。