「MySQL」タグアーカイブ

DENSE_RANKとRANKの違いを使い分けるランキング便利技

SQLでデータに順位を付けたいとき、よく使われるのが RANKDENSE_RANK です。
どちらもウィンドウ関数として利用でき、同点がある場合にどう順位を振るかが異なります。

「売上ランキングを作りたい」「部門ごとのTOP3を出したい」といった実務シーンでは、両者の違いを理解していないと期待通りの結果にならないことがあります。

本記事では、RANKとDENSE_RANKの基本的な違い を解説したうえで、実務での使い分け方、さらに DBMSごとのサポート状況 までわかりやすく紹介します。


RANKとは?

RANK は、同点がある場合に同じ順位を付けますが、その分次の順位が飛びます。

例:テストの点数ランキング

名前点数RANK
Aさん1001
Bさん952
Cさん952
Dさん904
 

👉 2位が2人いるため、次の順位は「4位」となります。


DENSE_RANKとは?

DENSE_RANK は、同点の場合も同じ順位を付けますが、次の順位は飛ばさずに連続します。

名前点数DENSE_RANK
Aさん1001
Bさん952
Cさん952
Dさん903

 

👉 2位が2人いても、次の順位は「3位」となります。


実務での便利な活用例

1. 売上ランキングを作る

売上データから各商品の順位を求めたいときは DENSE_RANK が便利です。

👉 同順位の商品があっても「順位が飛ばない」ので、一覧が見やすくなります。

2. 部門別ランキングを作る

「部門ごとにランキングを出したい」場合は、PARTITION BY を組み合わせます。

👉 部門ごとに順位がリセットされ、それぞれの中でランキングが作成されます。

3. TOP Nの商品を抽出する

「売上TOP3の商品を取得したい」といった場合は注意が必要です。

👉 RANK を使うと、3位が同点の場合に4件以上取得されることがあります。

DENSE_RANK なら「必ず3位まで」に限定できるため安全です。


DBMSごとの違い

Oracle Database

  • RANK / DENSE_RANK ともに早期からサポート

  • 標準SQLに準拠し、安定して利用可能

PostgreSQL

  • バージョン8.4以降でサポート

  • 標準SQL準拠のため、OracleやSQL Serverとほぼ同じ書き方で利用できる

MySQL

  • MySQL 8.0 以降で利用可能

  • それ以前(5.x系など)では未対応で、ユーザー変数を使った代替実装が必要

SQL Server (Microsoft)

  • 2005以降でサポート

  • 標準SQLと同じ感覚で利用可能

👉 まとめると:

  • Oracle / PostgreSQL / SQL Server → そのまま使える

  • MySQL 8.0以降 → 標準対応

  • MySQL 5.x以前 → 対応なし(代替実装が必要)


まとめ

  • RANK → 同順位があると次の順位が飛ぶ(例:1,2,2,4)

  • DENSE_RANK → 順位が連続(例:1,2,2,3)

  • 実務での使い分け:

    • 売上ランキング → DENSE_RANK

    • 部門別の表彰や順位 → RANK

    • TOP N抽出 → DENSE_RANK が安全

  • DBMSによってサポート状況が異なるため、特にMySQLはバージョンを確認することが重要

SQLでのランキング処理はシーンによって適切に関数を選ぶのがコツです。

正規表現(REGEXP)でSQLがもっと楽になる!実践パターン集

SQLの検索でよく使われる LIKE 句は便利ですが、複雑な条件指定には限界があります。
そこで強力な武器となるのが 正規表現(REGEXP)
この記事では、基本的な使い方からよく使うパターン、さらに「SQLで利用できる正規表現の一覧」をまとめました。


1. REGEXPの基本構文

SQLでは REGEXP を用いて文字列検索を行います。

➡ 名前が Aで始まるユーザー を抽出。

2. 使用できる正規表現の一覧(MySQL準拠)

SQLで使える代表的な正規表現を整理しました。
※DBエンジンにより若干差異あり(MySQL、PostgreSQL、Oracleなど)

パターン意味使用例
^行頭にマッチ^A → Aで始まる
$行末にマッチZ$ → Zで終わる
.任意の1文字c.t → cat, cot, cut
[...]文字クラス[0-9] → 数字1文字
[^...]否定の文字クラス[^0-9] → 数字以外
*0回以上の繰り返しa* → "", a, aaa
+1回以上の繰り返しa+ → a, aa
?0回または1回colou?r → color, colour
{n}n回の繰り返し[0-9]{4} → 4桁の数字
{n,}n回以上の繰り返し[0-9]{2,} → 2桁以上の数字
{n,m}n〜m回の繰り返し[A-Z]{2,5} → 2〜5文字の大文字
|OR条件cat|dog → cat または dog
()グループ化(abc)+ → abc, abcabc
[:digit:]数字[[:digit:]] → 0〜9
[:alpha:]英字[[:alpha:]] → A〜Z, a〜z
[:alnum:]英数字[[:alnum:]] → 英数字
[:space:]空白文字[[:space:]] → 空白, 改行, タブ
[:upper:]大文字[[:upper:]] → 大文字
[:lower:]小文字[[:lower:]] → 小文字

3. よく使う実践パターン

(1) 先頭・末尾の一致

➡ Pで始まる商品コード。

(2) 日付フォーマット判定

➡ “YYYY-MM-DD” を含むログ。

(3) メールアドレス判定

➡ GmailまたはYahooメール利用者を抽出。

(4) 商品コードの書式検証

アルファベット3文字+数字 の形式に一致。

(5) 拡張子フィルタ

➡ PDFファイルだけを抽出。

4. REGEXPのメリットと注意点

メリット

  • 複雑な条件をシンプルに表現できる

  • SQLの可読性が向上

  • データ品質チェックに有効

注意点

  • DBごとに正規表現エンジンが異なる(MySQL、PostgreSQL、Oracleで互換性に注意)

  • パフォーマンス低下の可能性があるため、大量データ処理時はインデックス設計と併用が望ましい


SQLでのREGEXPサポート比較(DBMSごと)

DBMSREGEXPサポート演算子/関数例備考
MySQLREGEXP, REGEXP_REPLACE8.0以降はICUベース
PostgreSQL~, ~*, !~, !~*高度な正規表現OK
OracleREGEXP_LIKE, REGEXP_SUBSTRPOSIX互換
SQL Server(CLR関数経由)ネイティブ未対応
SQLiteREGEXP(要自作関数)デフォルト非対応
BigQueryREGEXP_CONTAINS などクラウドSQL
SnowflakeRLIKE, REGEXPほぼMySQL互換

 

まとめ

REGEXPを使えばSQLの検索が格段に柔軟になります。
一覧表を参考に、ログ解析やメール判定、コード検証などに応用してみてください。

「LIKEでは表現できない…」と思ったら、REGEXPの出番です!