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つの方法

推薦する

IDEA で Docker プロジェクトをデプロイする手順

現在、ほとんどのプロジェクトが Docker 上にデプロイされ始めていますが、デプロイのプロセスはま...

forEachでawaitが機能しない問題を解決する

1. はじめに数日前、プロジェクトでトラバーサルに使用したときに落とし穴に遭遇し、解決するのに 1 ...

MySQL 8.0.22.0 のダウンロード、インストール、設定方法のグラフィックチュートリアル

MySQL 8.0.22のダウンロード、インストール、設定方法、参考までに具体的な内容は次のとおりで...

Vueコンポーネント通信のさまざまな方法の詳細な説明

目次1. 父から息子へ2. 息子から父へ3. 親子関係のないコンポーネントの値の転送4. ヴュークス...

Tomcat のセッションと Cookie の詳細な説明

序文HTTP はステートレスな通信プロトコルです。各リクエストは互いに独立しており、サーバーは以前の...

Mysql varchar型の合計操作例

友人の中には、データベースについて学習しているときに、テーブル構造を作成するときに誤ってフィールドを...

DockerはClickHouseをインストールし、データテストを初期化します

クリックハウスの紹介ClickHouse は、SQL クエリを使用して分析データ レポートをリアルタ...

JavaScript の isPrototypeOf 関数

目次1. isPrototypeOf()例 1、オブジェクト クラス インスタンス:例 2: Hum...

Node.js管理ツールnvmの詳細なインストール手順

いいえnvmはnodejsの複数のバージョンを管理する役割を担っています。インストール: https...

雨滴効果を実現する JavaScript キャンバス

この記事の例では、雨滴効果を実現するためのキャンバスの具体的なコードを参考までに共有しています。具体...

テーブルを作成するための HTML dl、dt、dd タグとテーブル作成テーブル

ウェブサイトの開発とメンテナンスのコストが削減されるだけでなく、コードもよりセマンティックになります...

Ubuntu16.04にCUDA9.0をインストールするための詳細なチュートリアル

序文:この記事は、CUDA 9.0 をインストールした経験に基づいています。CUDA 9.0 は現在...

Centos7.4 環境に lamp-php7.0 をインストールするチュートリアル

この記事では、Centos7.4 環境に lamp-php7.0 をインストールする方法について説明...

例を通してBRタグとPタグの違いを理解する

<br />改行タグの使用<br>改行タグ<br>は終わりのない...