こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

MySQLで対象期間を決め集計しランキングする方法

MySQLの初心者ですが、対象期間で集計を行いランキング付けし任意の上位何位までを抽出する方法について教えてください。
全データから集計後上位5位を選ぶ場合・・同順有り
select x.`品名`,x.kei,(select count(*)+1 from (select `品名`,sum(`金額`) as kei from uriage group by `品名`) y where x.kei<y.kei ) as rank
from (select `品名`,sum(`金額`) as kei from uriage group by `品名`) x
having rank <= 5
order by rank
といろいろ参考にしてで出来ましたが。任意の対象期間(日付)を設定して実行するSQL文が思いつきません。どこに期間を挿入するのか・・・悪あがきで思い付いた方法として
CREATE OR REPLACE VIEW uriage_01 AS
SELECT `品名`,SUM(`金額`) AS `金額` FROM uriage WHERE `日付` BETWEEN "2001/01/01" AND "2001/01/31" GROUP BY `品名`
で任意期間の集計結果のビューを作りそのビューから
select r1.`品名` as `品名`, r1.`金額` as p, count(r2.`金額`)+1 as rank
from uriage_01 as r1 left join uriage_01 as r2
on r1.`金額` < r2.`金額`
group by r1.`品名`
having rank <= 5
order by rank
と手間の掛かる方法です。単純に5行だけに限定ならorder by `金額`Limit 5 にすれば良いだけですけど・・・同順があるとどうすれば良いのかと思考停止状態です。尚、当方は、MySQLの勉強を始めたばかりにですので宜しくお願いいたします

投稿日時 - 2017-09-05 16:57:25

QNo.9371245

暇なときに回答ください

質問者が選んだベストアンサー

mysql 限定なら 変数を使って期間用データを指定すればいいのでは?
先にsetクエリで変数に値を代入しておけば、select句の相関クエリにも使えるだろう。
set @d1="20170101" d1, @d2="20170331";
select `品名`, kei ,(select count(*) +1 from
(select `品名`,sum(`金額`) as kei from uriage where `日付` BETWEEN @d1 AND @d2 group by `品名`) x2
where x1.kei<x2.kei ) rank
from (select `品名`,sum(`金額`) as kei from uriage where `日付` BETWEEN @d1 AND @d2 group by `品名`) x1
having rank<=5 order by rank;
アプリケーションから発行するのであれば、日付変数名のところをプレースホルダーにしてpreparedすれば、プレースホルダーが2カ所だろうが4カ所だろうが、置き換え順を間違わなければ、2番目のselect文一つで済む。

投稿日時 - 2017-09-06 20:58:09

補足

有難うございました。
set @d1="20170101" d1, @d2="20170331";
select `品名`, kei ,(select count(*) +1 from   でOKでした。この回答で自分が馬鹿やっていたの痛感しました。両方に期間設定するのを忘れて片側だけで試していてこんな馬鹿な質問をしました。現在試しいるは、通常使っているDBのfilemakerからODBC接続でSQLを実行することでその結果をfilemakerのインポートで取得するスクリプトを組むことです。100万件以上のレコードでは、filemakerのExecuteSQLのRANK関数ではとんでもない処理時間がかかるのでレコードをmysql側におき期間設定をfilemakerで設定しSQL文に自動的に組み込ませSQLの実行でmysqlで計算させその結果をインポートするものです。1行1レコードの問題はありますがここで関係ないので問題なし・・・こんな方法ですのでfilemakerで
set @d1="20170101" d1, @d2="20170331";
select `品名`, kei ,(select count(*) +1 from
は記述しても動かないので(select以降で変数定義する場合は別です・・・確か他の例では)setを使わず直接両方に期間設定する方法でOKでした。但しパフォーマンスは、ビューを使ったものと同じでしたが・・・
当方の馬鹿で未熟な質問にお答えいただき有難うございました

投稿日時 - 2017-09-07 06:41:21

お礼

補足とお礼欄間違えました。ここでもバカやっている。慣れないと駄目だ・・・
本当に有難うございました。

投稿日時 - 2017-09-07 06:51:14

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(1)