【SQL】ROW_NUMBER()でグループごとの連番を取得する【SQL Server】

【SQL】ROW_NUMBER()でグループごとの連番を取得する【SQL Server】

はじめに

コジマです。

例えば画面に表示されているデータをID順に連番を振りなおしたい場合なんかに使います。

シチュエーション

本の発注履歴を外部システムに連携したいとします。
こちらのシステムでは画面から登録した表示順にデータを管理していますが、
外部システムでは本のID順に表示順を登録しなおさないといけません。
こんな場合を想定して本記事で例を書き進めます。

/* 発注した本のデータ */
WITH order_books AS (
    SELECT 1 as book_id, 0 as sort_no
    UNION
    SELECT 3 as book_id, 1 as sort_no
    UNION
    SELECT 7 as book_id, 2 as sort_no
    UNION
    SELECT 2 as book_id, 3 as sort_no
    UNION
    SELECT 5 as book_id, 4 as sort_no
)
/* 本のマスタデータ */
, books AS (
    SELECT 1 as book_id, N'情弱を騙して儲ける本' as book_name
    UNION
    SELECT 2 as book_id, N'未経験からたった3か月でフリーランスになる本' as book_name
    UNION
    SELECT 3 as book_id, N'未経験から半年でAIエンジニアになる本' as book_name
    UNION
    SELECT 4 as book_id, N'スマホ一つでスキマ時間で稼ぐ本' as book_name
    UNION
    SELECT 5 as book_id, N'楽して稼ぐ10のコツ' as book_name
    UNION
    SELECT 6 as book_id, N'誰でもできるFX' as book_name
    UNION
    SELECT 7 as book_id, N'人脈こそパワー' as book_name
    UNION
    SELECT 8 as book_id, N'情弱を騙して儲ける本に騙される情弱にならない方法' as book_name
)
SELECT
    ob.book_id
    , b.book_name
    , ob.sort_no
FROM order_books ob
JOIN books b ON ob.book_id = b.book_id
ORDER BY book_id

出力結果

book_id book_name sort_no
1 情弱を騙して儲ける本 1
2 未経験からたった3か月でフリーランスになる本 4
3 未経験から半年でAIエンジニアになる本 2
5 楽して稼ぐ10のコツ 5
7 人脈こそパワー 3

本のID順に並べると表示順がぐちゃぐちゃになってしまいますね。
こういう時役立つのがROW_NUMBER() です。

ROW_NUMBER()を使う例

/* 発注した本のデータ */
WITH order_books AS (
    SELECT 1 as book_id, 1 as sort_no
    UNION
    SELECT 3 as book_id, 2 as sort_no
    UNION
    SELECT 7 as book_id, 3 as sort_no
    UNION
    SELECT 2 as book_id, 4 as sort_no
    UNION
    SELECT 5 as book_id, 5 as sort_no
)
/* 本のマスタデータ */
, books AS (
    SELECT 1 as book_id, N'情弱を騙して儲ける本' as book_name
    UNION
    SELECT 2 as book_id, N'未経験からたった3か月でフリーランスになる本' as book_name
    UNION
    SELECT 3 as book_id, N'未経験から半年でAIエンジニアになる本' as book_name
    UNION
    SELECT 4 as book_id, N'スマホ一つでスキマ時間で稼ぐ本' as book_name
    UNION
    SELECT 5 as book_id, N'楽して稼ぐ10のコツ' as book_name
    UNION
    SELECT 6 as book_id, N'誰でもできるFX' as book_name
    UNION
    SELECT 7 as book_id, N'人脈こそパワー' as book_name
    UNION
    SELECT 8 as book_id, N'情弱を騙して儲ける本に騙される情弱にならない方法' as book_name
)
SELECT
    ob.book_id
    , b.book_name
    , ob.sort_no
    -- 本のID順に連番を取得
    , ROW_NUMBER() OVER (ORDER BY ob.book_id) as new_sort_no
FROM order_books ob
JOIN books b ON ob.book_id = b.book_id
ORDER BY book_id

出力結果

book_id book_name sort_no new_sort_no
1 情弱を騙して儲ける本 1 1
2 未経験からたった3か月でフリーランスになる本 4 2
3 未経験から半年でAIエンジニアになる本 2 3
5 楽して稼ぐ10のコツ 5 4
7 人脈こそパワー 3 5

PARTITION BYを組み合わせることで、発注IDごとに連番を振るなんてこともできます。

/* 発注した本のデータ */
WITH order_books AS (
    SELECT 1 as order_id, 1 as book_id, 1 as sort_no
    UNION
    SELECT 1 as order_id, 3 as book_id, 2 as sort_no
    UNION
    SELECT 2 as order_id, 7 as book_id, 1 as sort_no
    UNION
    SELECT 2 as order_id, 2 as book_id, 2 as sort_no
    UNION
    SELECT 2 as order_id, 5 as book_id, 3 as sort_no
)
/* 本のマスタデータ */
, books AS (
    SELECT 1 as book_id, N'情弱を騙して儲ける本' as book_name
    UNION
    SELECT 2 as book_id, N'未経験からたった3か月でフリーランスになる本' as book_name
    UNION
    SELECT 3 as book_id, N'未経験から半年でAIエンジニアになる本' as book_name
    UNION
    SELECT 4 as book_id, N'スマホ一つでスキマ時間で稼ぐ本' as book_name
    UNION
    SELECT 5 as book_id, N'楽して稼ぐ10のコツ' as book_name
    UNION
    SELECT 6 as book_id, N'誰でもできるFX' as book_name
    UNION
    SELECT 7 as book_id, N'人脈こそパワー' as book_name
    UNION
    SELECT 8 as book_id, N'情弱を騙して儲ける本に騙される情弱にならない方法' as book_name
)
SELECT
    ob.order_id
    , ob.book_id
    , b.book_name
    , ob.sort_no
    -- 本のID順に連番を取得
    , ROW_NUMBER() OVER (PARTITION BY ob.order_id ORDER BY ob.book_id) as new_sort_no
FROM order_books ob
JOIN books b ON ob.book_id = b.book_id
ORDER BY ob.order_id, ob.book_id

出力結果

order_id book_id book_name sort_no new_sort_no
1 1 情弱を騙して儲ける本 1 1
1 3 未経験から半年でAIエンジニアになる本 2 2
2 2 未経験からたった3か月でフリーランスになる本 2 1
2 5 楽して稼ぐ10のコツ 3 2
2 2 人脈こそパワー 1 3

使い方を簡単に

ROW_NUMBER() OVER (条件) AS 別名

この構文を覚えておきましょう。

さいごに

ROW_NUMBER()はウインドウ関数と呼ばれるものの一つで、他にもいろいろ種類があります。
ここでは触れませんが、また覚えたものを記事にできればな~と思っている次第です。

この記事を面白いまたは役に立ったと思ってくれた方は是非私のTwitter(@kojimanotech)を
フォローしてくれたらうれしいです!

もっと学びたい人はこちら

SQLをもっと学びたいエンジニアのためにおすすめのUdemy講座を紹介いたします!

SQLはじめましての人!まずあなたの3時間をください。
この講座でまずこれだけは覚えてくれ!という内容をしっかり押さえることができます。
SQLはプログラミング言語がなんであれ、システム開発に必要になります。
この講座を見て最低限必要な知識を身に着けて実践で貢献できるようになりましょう!
3時間で学ぶ SQL ・データベース 超入門【丁寧な解説+演習問題で SQL データ抽出の基本が身につく】標準 SQL

データベースの設計について学べる講座です。
設計について学べる教材は少ないので、実務でデータベースを触る人にはとてもうれしい講座です。
データベース講座1:データベース論理設計

ちょっとニッチに感じるかもしれませんが、SQLのインデックスを学ぶことができる講座です。
よい性能でSQLを運用するためにはインデックスの理解は必要不可欠です。
CRUD書いて満足するエンジニアを出し抜きましょう。
SQLServerのインデックスを理解して検索を速くする方法

気になった人はぜひ見てみてくださいね!
以上、コジマでした。


SQLカテゴリの最新記事