質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

Q&A

解決済

3回答

3113閲覧

MYSQL タイ順位を表示させ、ユーザーを重複させたくない

mendax

総合スコア13

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

0グッド

0クリップ

投稿2018/11/15 12:00

編集2018/11/15 14:19

前提

MYSQLのテーブルの内容

user_idpoints(ユーザー獲得ポイント)exam_id(クイズのレベル)
11305
41501
11505
81505
41405
561203
32705
32105
11105

クイズのサイトを作成しています。上記のテーブルを使用して、ユーザーを高得点順にランキング形式で表示させたいと思っています。

実現したいこと

実現したい内容

user_idpointsexam_idRANK
115051(位)
815051(位)同位の場合はタイ表示
414053(位)
327054(位)
111055(位)

■同位がある場合はタイ表示
■exam_id毎に表示させる
■各user_idは重複させず、高得点のみ表示

試した事 / 質問点

user_idpointsexam_idRANK備考
115051
815051
414052
113053←user_idは高得点のみ表示させ、重複させたくない
327054
321055←user_idは高得点のみ表示させ、重複させたくない
111055

下記該当のソースコードでランクのタイ表示はできたのですが、クイズは何度でも受けられる事から、上の表の様にuser_id 1やuser_id 32が重複してランクインされてしまいます

user_idは重複させず、なおかつ、排除した分はランクが繰り上がる様にしたいのですが、どの様な書き方がよいのでしょうか?

よろしくお願いいたします。

該当のソースコード

SELECT user_id, points, exam_id, (SELECT COUNT(DISTINCT points) FROM ranking b WHERE exam_id='5' AND a.points < b.points ) + 1 rank FROM ranking a WHERE exam_id='5' -- クイズのレベル ORDER BY rank ASC

補足情報(バージョンなど)

phpMyAdmin
バージョン情報: 4.7.9

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2018/11/15 12:11

実現したい内容にはid=4が抜けているのはなぜ?exam_id=5のデータもありますよね
mendax

2018/11/15 12:43

ご回答、ご指摘いただきありがとうございます! おっしゃる通りid=4もexam_id=5に入りますので、表を修正いたしました。
sazi

2018/11/15 14:37

ユーザーの自身の得点が同じだった場合でも、rankingの件数は受けた件数分ですか?
guest

回答3

0

MySQL8.0以降なら分析関数が使えるのに。。

SQL

1select user_id, max_points 2 ,(select count(distinct max_points) +1 3 from ( 4 select user_id, max(points) as max_points 5 from ranking 6 where exam_id=5 7 group by user_id 8 ) v2 9 where max_points < v1.max_points 10 ) rank 11from ( 12 select user_id, max(points) as max_points 13 from ranking 14 where exam_id=5 15 group by user_id 16) v1

上記はdense_rank()【同率があった場合順位は同じになり、その次は順位を飛ばさない】と同じ。
質問がrank()【同率があった場合順位は同じになり、その次は順位を飛ばす】に変更されているので、以下
※DISTINCTを付けない

SQL

1select user_id, max_points 2 ,(select count(max_points) +1 3 from ( 4 select user_id, max(points) as max_points 5 from ranking 6 where exam_id=5 7 group by user_id 8 ) v2 9 where max_points < v1.max_points 10 ) rank 11from ( 12 select user_id, max(points) as max_points 13 from ranking 14 where exam_id=5 15 group by user_id 16) v1

下記なども参考にして下さい。
SQLのCOUNTカラムに順位をつけるには

投稿2018/11/15 14:48

編集2018/11/16 00:52
sazi

総合スコア25195

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mendax

2018/11/15 22:38

ご回答いただきありがとうございます!また構文を書いてくださりありがとうございます! 分析関数というのがあるのですね。。まだSQLに触れて日が浅いのでとても勉強になります。 既に問題は解決できましたが、様々なパターンのコードをかける様にsaziさんの構文も参考にさせていただきます。今後もよろしくお願いいたします。
mendax

2018/11/16 08:28

上記二つの構文を試したところ、実現したい内容が実行できました! 【同率があった場合順位は同じになり、その次は順位を飛ばす】に変更をしていたのですが、どちらのパターンも知りたい事でしたので大変参考になりました。 調べてみたら分析関数の方が効率よくコードをかけると知り今後ランキングなどの集計には重宝しそうです。 ご丁寧な解説重ね重ね誠にありがとうございます!
guest

0

投稿2018/11/15 12:08

Orlofsky

総合スコア16415

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mendax

2018/11/15 14:42

IF(A,B,C)関数で順位を作成する発想がなかったので、とても参考になりました! 別の解答で解決はしたのですが、こちらも後学の為に、色々勉強したいと思います! ご回答いただきありがとうございます!
guest

0

ベストアンサー

SQL

1select t1.*, 2(select count(*)+1 from ranking as t2 3where t2.exam_id=t1.exam_id 4and not exists( 5select 1 from ranking 6where user_id=t2.user_id 7and exam_id=t2.exam_id 8and points>t2.points) 9and t2.points>t1.points 10) as rank 11from ranking as t1 12where exam_id=5 13and not exists( 14select 1 from ranking 15where user_id=t1.user_id 16and exam_id=t1.exam_id 17and points>t1.points) 18

投稿2018/11/15 13:16

yambejp

総合スコア114843

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mendax

2018/11/15 13:58

構文まで書いていただき、また迅速なご回答ありがとうございます!勉強になります。 構文を試してみたところ、user id 1のみ重複され、それ以外は重複は出ないようになりました! またuser id 1の重複のせいか、その部分のみランクの表示が正常に出ない様になっておりました。。 (下記画像参照) https://imgur.com/NZRgRdf なお、いただいた構文からORDER BY rank ASC のみ最後に付け加えております。 こちらを参考に私の方でもいろいろ試してみます。
mendax

2018/11/15 14:37

すみません。今気づいたのですが、yambejpさんの構文の不具合ではなく。 同idが高得点を2回出した場合だと、重複されるという問題でした。 なので、先ほどの問題もselect DISTINCT t1.user_idでuser id 1の重複がなくなりました。 お手数おかけしてすみません。 yambejpさんの解答で解決できましたので、ベストアンサーとさせていただきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問