MySQL における一般的なランキングの問題をいくつかまとめます

MySQL における一般的なランキングの問題をいくつかまとめます

序文:

一部のアプリケーション シナリオでは、成績や年齢によるランキングなど、ランキングの問題が発生することがよくあります。直接ランキング、グループランキング、間隔付きランキング、間隔なしランキングなど、ランキングの方法は多数あります。この記事では、MySQL における一般的なランキングの問題をいくつかまとめます。

テストテーブルを作成する

テーブルscores_tbを作成する(
 id int auto_increment 主キー、
 xuehao int が null ではない、 
 スコア int が null でない
)ENGINE=InnoDB デフォルト文字セット=utf8;
scores_tb (xuehao,score) に値 (1001,89),(1002,99),(1003,96),(1004,96),(1005,92),(1006,90),(1007,90),(1008,94) を挿入します。

# 挿入されたデータを表示しますmysql> select * from scores_tb;
+----+--------+-------+
| id | xuehao | スコア |
+----+--------+-------+
| 1 | 1001 | 89 |
| 2 | 1002 | 99 |
| 3 | 1003 | 96 |
| 4 | 1004 | 96 |
| 5 | 1005 | 92 |
| 6 | 1006 | 90 |
| 7 | 1007 | 90 |
| 8 | 1008 | 94 |
+----+--------+-------+

1. 普通順位

行番号と同様に、スコアによって直接ランク付けします。1 から始まり、下に向かっていきます。以下にクエリステートメントとランキング結果を示します。

# クエリステートメント SELECT xuehao, score, @curRank := @curRank + 1 AS rank
scores_tb から、(
@curRank := 0 を選択
)
スコア降順で並べ替え;

# 結果の並べ替え +--------+-------+------+
| xuehao | スコア | 順位 |
+--------+-------+------+
| 1002 | 99 | 1 |
| 1003 | 96 | 2 |
| 1004 | 96 | 3 |
| 1008 | 94 | 4 |
| 1005 | 92 | 5 |
| 1006 | 90 | 6 |
| 1007 | 90 | 7 |
| 1001 | 89 | 8 |
+--------+-------+------+

上記のクエリ ステートメントでは、変数 @curRank を宣言し、0 に初期化します。行が見つかったら、変数を 1 増やし、それをランキングとして使用します。このタイプのランキングには差がなく、スコアは同じでもランキングが異なるものがあることがわかります。

2. スコアは同じ、順位も同じ、順位に差はない

# クエリステートメント SELECT xuehao, score, 
場合
@prevRank = スコアの場合、@curRank
@prevRank := スコアの場合、@curRank := @curRank + 1
END ASランク
scores_tbより、 
(@curRank := 0、@prevRank := NULL を選択)
スコア降順で並べ替え;

# ランキング結果+--------+-------+------+
| xuehao | スコア | 順位 |
+--------+-------+------+
| 1002 | 99 | 1 |
| 1003 | 96 | 2 |
| 1004 | 96 | 2 |
| 1008 | 94 | 3 |
| 1005 | 92 | 4 |
| 1006 | 90 | 5 |
| 1007 | 90 | 5 |
| 1001 | 89 | 6 |
+--------+-------+------+

3. 順位は同点、順位に差あり

別のランキング方法は、同じ値には同じランキングがあり、同じ値の次のランクはジャンプする整数値である必要がある、つまり、ランキングにギャップがあるというものです。

# クエリステートメント SELECT xuehao, score, rank FROM
(選択 xuehao、スコア、
@curRank := IF(@prevRank = スコア、@curRank、@incRank) AS ランク、 
@incRank := @incRank + 1、 
@prevRank := スコア
scores_tb から、(
@curRank := 0、@prevRank := NULL、@incRank := 1 を選択
)
ORDER BY スコア desc) s;
# ランキング結果+--------+-------+------+
| xuehao | スコア | 順位 |
+--------+-------+------+
| 1002 | 99 | 1 |
| 1003 | 96 | 2 |
| 1004 | 96 | 2 |
| 1008 | 94 | 4 |
| 1005 | 92 | 5 |
| 1006 | 90 | 6 |
| 1007 | 90 | 6 |
| 1001 | 89 | 8 |
+--------+-------+------+

上記で紹介した 3 つのランキング方法は、実装が比較的複雑です。幸いなことに、MySQL 8.0 ではウィンドウ関数が追加され、組み込み関数を使用して上記のランキングを簡単に実現できます。

MySQL 8.0はウィンドウ関数を使用してランキングを実装します

MySQL 8.0 では、ROW_NUMBER()、DENSE_RANK()、RANK() の 3 つのウィンドウ関数を使用して、上記の 3 つのランキングを実装できます。注意すべき点は、as の後のエイリアスは前の関数名と同じであってはならないということです。同じでない場合、エラーが報告されます。以下は、ランキングを実装するこれらの 3 つの関数の例です。

# 上記の 3 つのランキングに対する 3 つのステートメント select xuehao,score, ROW_NUMBER() OVER(order by score desc) as row_r from scores_tb;
scores_tb から、xuehao、スコア、DENSE_RANK() OVER(スコア降順) を concentration_r として選択します。
scores_tb から xuehao,score, RANK() over(order by score desc) as r を選択します。

# 1つのステートメントで異なるランキングを照会することもできます SELECT xuehao,score,
 ROW_NUMBER() OVER w AS 'row_r'、
 DENSE_RANK() OVER w AS 'dense_r'、
 RANK() OVER w AS 'r'
`scores_tb` から
WINDOW w AS (ORDER BY `score` desc);

# ランキング結果+--------+-------+-------+---------+---+
| xuehao | スコア | row_r | dense_r | r |
+--------+-------+-------+--------+---+
| 1002 | 99 | 1 | 1 | 1 |
| 1003 | 96 | 2 | 2 | 2 |
| 1004 | 96 | 3 | 2 | 2 |
| 1008 | 94 | 4 | 3 | 4 |
| 1005 | 92 | 5 | 4 | 5 |
| 1006 | 90 | 6 | 5 | 6 |
| 1007 | 90 | 7 | 5 | 6 |
| 1001 | 89 | 8 | 6 | 8 |
+--------+-------+-------+--------+---+

要約:

この記事では、3 つの異なるシナリオで統計ランキングを実装するための SQL ステートメントについて説明します。さまざまなビジネス ニーズに基づいて適切なランキング ソリューションを選択できます。 MySQL 8.0 と比較すると、ウィンドウ関数を使用するとランキングがより簡単になります。実際、ビジネス要件はここで示した例よりもはるかに複雑です。SQL を使用してこのようなビジネス要件を実装するには、経験を積むのにまだ時間がかかります。

上記は、MySQL におけるいくつかの一般的なランキングの問題の詳細な要約です。MySQL ランキングの詳細については、123WORDPRESS.COM の他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • MYSQL は、指定されたユーザーのランキングとクエリを実装します。ランキング関数 (並列ランキング関数) のサンプルコード
  • ランキングを取得するためのMySQLソートの例コード
  • MySQL ページアクセス統計とランキング
  • MySQL でカスタム フィールド クエリ結果にランキングを追加する方法
  • MySQL のグループ化により、group by と order by の調査で各グループの最初の数件のレコードを取得します (ランキング)

<<:  Linux trコマンドの使用

>>:  Vueユーザーが長時間操作せずにログインページからログアウトするように実装する2つの方法

推薦する

ユーザーはその理由を知る必要がある

証券会社にいた頃、設計業務が忙しくなかったため、商品のマニュアルを書く役割を担ったことがありました。...

Windows10でmysql8.0.17を置き換える詳細なチュートリアル

この記事では、Windows10でmysql8.0.17を置き換える具体的な手順を参考までに紹介しま...

React 入門レベルの詳細なメモ

目次1. Reactの基本的な理解1. はじめに2. Reactの特徴3. Reactが効率的な理由...

Docker パッケージング ノード プロジェクトのプロセスの説明

バックエンド プログラマーとして、フロントエンドのものをいじらなければならないこともあります。そこで...

MySQL ジョイントテーブルクエリの簡単な例

MySql は結合テーブルクエリを使用しますが、初心者には理解しにくい場合があります。以下の記事では...

MySQL マスタースレーブレプリケーションと読み取り書き込み分離の詳細な説明

目次序文1. 概要2. 読み取りと書き込みの分離3. MySQL マスタースレーブレプリケーションの...

Linux でジャンクファイルをエレガントに削除する方法

あなたも私と同じように、コンピューターのファイルを整然と整理し、不要なファイルを適宜削除するプログラ...

良いリファクタリングを行うには、コードをリファクタリングするだけでなく、人生をリファクタリングすることも重要です。

職業的な観点からも、人生の観点からも、良い再建をすることは本当に簡単ではありません。楽観的で熱心で前...

MySQL バッチ挿入ループの詳細なサンプルコード

背景数日前、MySql でページングを行っていたときに、ページングに制限 0,10 を使用するとデー...

HTMLは入力完了を検出する機能を実装する

入力が進行中かどうかを検出するには、「onInput(event)」を使用しますコンテンツが変更され...

JavaScript の構成と継承の説明

目次1. はじめに2. プロトタイプチェーン継承3. コンストラクタの継承4. 組み合わせ継承1. ...

ユーザーエクスペリエンスの要素またはWebデザインの要素

システムとユーザー環境の設計<br />Apple システムの成功は、そのシステム アー...

MySQL 8.0 のメモリ関連パラメータの概要

理論的には、MySQL によって使用されるメモリ = グローバル共有メモリ + max_connec...

Vue 条件付きレンダリング v-if と v-show

目次1. 動詞-if 2. <template> で v-if を使用する3. キーを使...

JS 1次元配列を3次元配列に変換する例

今日、CSDN の Q&A セクションで友人が質問をしているのを見ました。彼は 1 次元配列...