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

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

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

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

3056閲覧

ユーザーのスコア(ポイント)を記録、ランキング化したい

merryken

総合スコア30

MySQL

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

データベース

データベースとは、データの集合体を指します。また、そのデータの集合体の共用を可能にするシステムの意味を含めます

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

1クリップ

投稿2017/03/22 08:43

##質問内容
ユーザーのスコア(ポイント)を、ランキング用のテーブルを作成し定期的にバッチ処理で集計しようと考えています。

①日、週、月のランキング
②前回との順位の比較(昨日2位、今日1位だった場合「UP」のようなイメージ)

上記のようなことを実現したいのですが、DB設計はどのようにするといいでしょうか?
よろしくお願いします。

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

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

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

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

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

guest

回答1

0

ベストアンサー

ユーザーIDごとに順位の基準となるポイントと期日を記録しておけばよいでしょう。

デイリーラインキングはいいとして週と月ってどういう計算ですか?
週は月曜から日曜のデイリーポイントの積み上げなのでしょうか?
それとも最終日(たとえば日曜)の時点のポイントなのでしょうか?

その辺の仕様がわからないとどうしようもないですね。
ちなみにランキングは定番の書き方があります。

sample1

とりあえずデイリーランキングのサンプルです

  • 元データ

SQL

1create table score(id int primary key auto_increment,uid int,d date,point int,unique(uid,d)); 2insert into score(uid,d,point) values 3(1,'2017-03-01',100), 4(2,'2017-03-01',110), 5(3,'2017-03-01',120), 6(1,'2017-03-10',100), 7(2,'2017-03-10',200), 8(3,'2017-03-10',80), 9(4,'2017-03-10',50), 10(1,'2017-03-20',300), 11(2,'2017-03-20',200), 12(4,'2017-03-20',130), 13(5,'2017-03-20',120), 14(6,'2017-03-20',120), 15(7,'2017-03-20',140);
  • とりあえず3/20のランキング

SQL

1select uid,point,(select count(*)+1 from score as t2 where t1.point<t2.point and t1.d=t2.d) rank 2from score as t1 3where d='2017-03-20' 4order by rank;
  • 3/10から3/20へのアップダウン

SQL

1select t3.uid,t3.point,t3.rank,t4.point as prepoint,t4.rank as prerank 2,case when t4.rank is null then 'up' when t3.rank<t4.rank then 'up' when t3.rank=t4.rank then '-' else 'down' end as shift 3from(select uid,point,(select count(*)+1 from score as t2 where t1.point<t2.point and t1.d=t2.d) rank 4from score as t1 5where d='2017-03-20') as t3 6left join ( 7select uid,point,(select count(*)+1 from score as t2 where t1.point<t2.point and t1.d=t2.d) rank 8from score as t1 9where d='2017-03-10' 10) as t4 on t3.uid=t4.uid 11order by rank; 12

sample2

月で集計したランキング

SQL

1select t1.uid,t1.point,count(*) as rank 2from (select uid,sum(point) as point from score where d between '2017-03-01' and '2017-03-31' group by uid) as t1 3inner join (select uid,sum(point) as point from score where d between '2017-03-01' and '2017-03-31' group by uid) as t2 4on t1.point<=t2.point 5group by t1.uid 6order by rank;

投稿2017/03/22 09:03

編集2017/03/23 06:16
yambejp

総合スコア114572

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

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

merryken

2017/03/22 10:27

ご回答ありがとうございます。説明不足で申し訳ございません。 ①日毎のスコア(ポイント)を記録、②期間を指定し週・月の順位を判定、ということを考えておりましたが、この考え方で正しいのでしょうか?また、「前回との順位の比較」に関しては、順位用のテーブルなどを用意した方がいいのでしょうか? ランキングの定番の書き方があるとのことですが、差し支えなければ教えて頂けますと幸いです。 質問ばかりで申し訳ありませんが、何卒よろしくお願いします。
yambejp

2017/03/23 03:01 編集

運用方法がよくわかりません たとえばユーザーAが3/21でポイント100だったとき3/22に何もしなかったら ・3/22はポイント100をキープするのか?(積み上げ) ・それとも3/22はポイント0なのか?(日毎) によって処理がことなります。週や月のランクの根拠もわかりません。 具体的なサンプルデータを提示してもらわないと書きようがないですね
merryken

2017/03/23 05:18

何度も申し訳ございません。 >それとも3/22はポイント0なのか?(日毎) 日毎のスコア(ポイント)を記録することを考えているので、こちらの運用方法となります。 週・月に関しては下記の通りです。 週:3/22〜7日間の合計 月:3/22〜31日間の合計 ただ、これが正しい運用方法なのかはわからないので、その部分も含めてのご質問でした。
yambejp

2017/03/23 05:20

上記仕様提示でなんとなくわかりました 調整します
merryken

2017/03/23 05:54

うまく説明できず、お手数おかけし申し訳ございません。よろしくお願いします。
yambejp

2017/03/23 06:17

デイリーランキング、マンスリーランキングを書いておきました ウィークリーはその応用でできると思います
merryken

2017/03/23 08:41

具体的なコードまで本当にありがとうございます! 最後に、 「前回との順位の比較(昨日2位、今日1位だった場合「UP」のようなイメージ)」 に関してなのですが、こちらはどのようにするといいでしょうか? day、yesterday、week、lastweekのようなカラムを用意して順位を格納するような方法でいいのでしょうか? ※dayとyesterdayを比較してUP、DOWNを判断するイメージを考えています。
yambejp

2017/03/23 08:51

> 前回との順位の比較(昨日2位、今日1位だった場合「UP」のようなイメージ) え?サンプルに書いてありますよ 3/10と3/20にしてありますが、これを3/20と3/21など続けた日を 指定すればいいのでは? (サンプルデータをあまり投入していないので今回の例では 連続した日付でとれませんけどね)
merryken

2017/03/31 07:40

コードを参考に対応することができましたので、ベストアンサーにさせて頂きました。 お忙しいところご回答ありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問