MySQLで特定のグループの上位3件を取得する方法

このQ&Aのポイント
  • MySQLで特定のグループの上位3件を取得する方法について教えてください。条件として、userでグループ化し、日付の降順で並べ、userごとに最新の3件のデータを取得したいです。
  • MySQLで特定のグループの上位3件を取得する方法について教えてください。userでグループ化し、日付の降順で並べ、userごとに最新の3件のデータを取得するためのSQL文を教えてください。
  • MySQLで特定のグループの上位3件を取得する方法について教えてください。userでグループ化し、日付の降順で並べ、最新の3件のデータを取得するためのSQL文を教えてください。
回答を見る
  • ベストアンサー

MySQLで特定のグループの上位3件を取得したい。

ちょっと壁に当たったので、わかる範囲でお答え頂きたいのですが、 以下のようなテーブルがあったとします。 id user price date 1 A 1000 2013/5/31 2 A 1200 2013/6/1 3 B 1000 2013/5/20 4 A 1500 2013/5/12 5 C 1300 2013/5/31 6 C 1400 2013/5/14 7 C 1000 2013/5/6 8 B 1100 2013/5/24 9 B 1200 2013/5/30 10 B 1100 2013/5/4 11 A 1800 2013/4/12 12 C 900 2013/4/6 ・・・ 次に取得したいのは、 A 1200 2013/6/1 A 1000 2013/5/31 A 1500 2013/5/12 C 1300 2013/5/31 C 1400 2013/5/14 C 1000 2013/5/6 B 1200 2013/5/30 B 1100 2013/5/24 B 1000 2013/5/20 このようなデータなのですが、 条件: 1.userでグループ化したうちの日付降順で並べる 2.そのuserのデータの中で、日付降順で並べる 3.userのデータが複数あっても、取得するのは新しいものから3件のみ この条件を満たすSQL文はどのように記述すればよいか、お知恵をお貸し下さい。 よろしくお願いします。

  • MySQL
  • 回答数4
  • ありがとう数1

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

  • ベストアンサー
  • root139
  • ベストアンサー率60% (488/809)
回答No.2

#1です。少し訂正が有ります。 複数の user の最新の日付が同じ場合に、それらのuserのデータが混ざって出力される可能性が有るので、ORDER BY句に user も含めるべきでした。 SELECT * FROM tbl_hoge a WHERE (SELECT COUNT(*) FROM tbl_hoge b WHERE a.user = b.user AND a.date < b.date) < 3 ORDER BY (SELECT MAX(date) FROM tbl_hoge c WHERE a.user = c.user) DESC, user, date DESC ;

ok-rjak
質問者

お礼

ありがとうございました! 希望通りの抽出が行えました。 実際のSQL文はもう少し複雑なのですが、提示して頂いた例を参考にアレンジさせて頂きました。 まだまだ勉強中の身ですので、またお世話になる際はよろしくお願いします。

その他の回答 (3)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.4

>3.userのデータが複数あっても、取得するのは新しいものから3件のみ まで考えるとidも比較しなくてはいけないかもしれないですね select * from テーブル as t1 where (select count(*) from テーブル as t2 where t1.user=t2.user and (t1.date<t2.date or t1.date=t2.date and t1.id<t2.id) ) <3 order by (select max(`date`) from テーブル as t3 where t1.user=t3.user) desc ,user ,`date` desc

  • nora1962
  • ベストアンサー率60% (431/717)
回答No.3

http://note.chiebukuro.yahoo.co.jp/detail/n181988 参考にしてください。 CNT列はグルーピングごとにカウントアップするのでこれをWHERE条件で絞ればいいかなと思います。

  • root139
  • ベストアンサー率60% (488/809)
回答No.1

下記の様なSQLで出来るかと。 version 5.5.8 で確認しました。 SELECT * FROM tbl_hoge a WHERE (SELECT COUNT(*) FROM tbl_hoge b WHERE a.user = b.user AND a.date < b.date) < 3 ORDER BY (SELECT MAX(date) FROM tbl_hoge c WHERE a.user = c.user) DESC, date DESC > 1.userでグループ化したうちの日付降順で並べる user 単位では最新の日付の降順になるということですよね? ORDER BY句の自己結合で同じuserの中で最新の日付を取得して実現しています。 > 2.そのuserのデータの中で、日付降順で並べる 同一の user のデータ同士も日付の降順になるということですよね? ORDER BY句の date DESC で実現しています。 > 3.userのデータが複数あっても、取得するのは新しいものから3件のみ WHERE句の自己結合で実現しています。 同じuserでそれより新しい日付のデータが3件未満という意味です。

参考URL:
http://codezine.jp/article/detail/460

関連するQ&A

  • Groupの中の条件に合致するデータを抜き出したい

    Groupの中の条件に合致するデータを抜き出したい いくつかのテーブルからGroupでくくったデータを抜き出しました。 その中から条件に合致するデータに絞りたいのですが、 思った結果となってくれません。 DB:MySQL 5.1.50 以下のようなことをしたいと考えています。 [元のデータ] ID   | 日付   | 担当   | 金額 A-01  |2010-09-01 |Angas    |1000 A-01  |2010-08-31 |Mayor    |1500 A-01  |2010-08-25 |Angas    |2000 B-01  |2010-08-30 |Roger    |1350 B-01  |2010-09-01 |Angas    |2000 B-01  |2010-08-20 |Roger    |1350 [結果として欲しいデータ] ID   | 日付   | 担当   | 金額 A-01  |2010-09-01 |Angas    |1000 A-01  |2010-08-31 |Mayor    |1500 B-01  |2010-08-30 |Roger    |1350 B-01  |2010-09-01 |Angas    |2000 ちょっとデータ例が貧弱ですが・・・ IDと担当でグループ化した中で、日付が最も大きいレコードを抜き出したい。 というのが目的です。 どのようにSQLを書くと良いのでしょうか? IDと担当でグループ化までは書けたのですが、 「グループのデータの中で日付で降順としたものの最新」というのを どのように書いたものか悩んでいます。 PS.こういうSQLの書き方で悩んだ時に、どうやって情報を集めると 良い情報に出合えるかの助言も頂ければ助かります。 よろしくお願いします。

  • MySQL複数テーブルからの情報取得に関しまして

    Aテーブル...ユーザ情報 Bテーブル...商品情報(AテーブルのユーザIDを列として持っています) Cテーブル...アイテム情報(Bテーブルの商品IDを列として持っています) Bテーブルの一覧リスト表示の画面にて、検索項目として、 Aテーブルのユーザ名、Cテーブルのアイテム名があります。 現在は、LEFT JOINを使って、検索、呼び出しを行っておりますが、 多数のカラムを指定して呼び出しを行っているため、SQL文が長くなってしまっており、 もっとすっきりとしたSQL文を記述したいと考えております。 ※Aテーブル,Bテーブルの組み合わせは他の画面でもよく使われております。 viewという機能を使うことによって、これをすっきりと記述できるようになるのではないかと考えておりますが、viewはこのような使い方をしてもいいのでしょうか。 または、もっとすっきりとした記述を行う技術のアドバイスをお願いいたします。 よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • Oracleで7日以内のデータ取得したい

    SQLの初心者です。 A・・・日付(テキストデータ) B・・・ユーザ名とします。 C・・・テーブル名 select A,B form C where (本日から7日以内) で取得したいのですが、どうしてもうまく行きません。 WHERE SYSDATE -7 and SYSDATE という気持ちにしたいのですが、教示していだけませんでしょうか?よろしくお願いします。

  • SQL GROUPで件数の一番多いレコードのみ取る

    SQL GROUPで件数の一番多いレコードのみ取る ORACLE10です。 次のようなテーブルがあります。 USER -----------テーブル名 ID,NAME,DATA----列名 1,A,any 1,A,any 1,B,any 2,C,any 3,D,any このテーブルから、IDをGROUPにして、さらに、一番使用頻度の多いNAMEを取得したいのです。 表示したいのは、IDとNAMEです。 つまり、取得結果例は次のようになります。 取得結果例 ID,NAME----列名 1,A 2,C 3,D SQL文をどのように作れば可能でしょうか? ちなみに、IDやNAMEのマスタテーブルはありません。 自分では、「(select ID, NAME, count(*) from USER group by ID, NAME) COUNT」で、COUNTを内部テーブルにして、グループ内で一番多いcount(*)をmaxで取得してみようかと思ったんですが、そこからアイデアが出ませんでした。

  • Oracle:グループごとに最大日付の行を1件取得

    Oracle11gで、以下のようなテーブルから、 「IDごとに、DTが最大のレコードのBUMONを1件ずつ取得」 したいです。 <テーブルTB> ID DT BUMON ------------- 1 9/1 A 1 9/2 A 1 9/3 B ★Bを取得したい 2 9/4 C 2 9/5 C ★Cを取得したい 3 9/1 D 3 9/3 E 3 9/3 E ★Eを取得したい <取得したいデータ> BUMON ------- B C E <考えたSQL> select distinct A.BUMON from (select ID, DT, max(DT) over(partition by ID) as MAXDT, BUMON from TB) A, (select ID, DT, max(DT) over(partition by ID) as MAXDT, BUMON from TB) B where A.ID = B.ID and A.DT = B.MAXDT ; 上記のような方法を考えましたが、取得できますでしょうか? 現在、SQL実行環境がない場所にいるのですが、急ぎで確認したく、 どなたかお知恵を拝借できませんでしょうか?? また、可能であれば、★のレコード全体を取得するSQLもご教授いただきたく存じます。 <★のレコード全体を取得した結果> ID DT BUMON ------------- 1 9/3 B 2 9/5 C 3 9/3 E

  • 特定条件の下でグループ化

    お世話になります。 SQL文でご質問があります。 たとえば以下のようなデータがあったとします。 項目1, 項目2, 項目3, 項目4 -------------------------------- 1  ,  A  ,  0  ,  10 2  ,  A  ,  0  ,  20 3  ,  B  ,  1  ,  30 4  ,  B  ,  0  ,  40 5  ,  C  ,  0  ,  50 6  ,  C  ,  0  ,  60 7  ,  D  ,  1  ,  70 8  ,  D  ,  1  ,  80 9  ,  E  ,  0  ,  90 10  ,  E  ,  1  ,  100 ここから[項目3] = 1 のレコードが含まれているもの に限り[項目2]でグループ化し、 [項目4]の合計値を求めて 項目2   ,   項目4 --------------- B  ,  70 D  ,  150 E  ,  190 と取得したいのですが、1回のSQL文で取得できるのでしょうか? ご存知のかたがいらっしゃいましたら、どうかご教授ください。m(__)m

  • 2つの情報を1つのSQLで取得する方法について

    お世話になります。 SQL文で、下記内容のデータを取得する方法がわかりません。 ・TESTテーブルからA、B、Cの3項目のデータを取得する。 ・但し、この中のC項目については、WHERE句の条件を満たす データの最大値を取得する。 ・項目AおよびBの取得条件は、項目Cと同一条件とする。 ・目的は、項目AおよびBに関しては、WHERE句の条件を満たす  全てのレコードを取得し、項目Cにおいては最大値のみ取得したい。 上記内容を取得しようと考えた場合、 現時点で下記のSQL文を作成して実行しましたが、 うまくデータが取得できません。 SELECT A, B, C FROM TEST WHERE C = (SELECT MAX(C) FROM TEST) AND Z = 'xxxxx' AND Y = 'x' AND X = 'Y' ※項目X, Y, ZはTESTテーブルのカラムです ※上記SQLを、A、Bのみ取得用とCのみ取得用に   それぞれ分解して実行すると、それぞれの結果は   正常に取得できます。 2つの結果を1つのSQLで取得することは可能でしょうか? どなたかご教授願えますか?よろしくお願いいたします。

  • ある条件でのSQLの取得方法について

    以下の条件でのSQLのデータの取得方法が分かりません。 2つのテーブルがあるとします。 ・テーブルA キー   項目1 10     X 20     Y ・テーブルB キー  項目2  項目3 10     5    C 10     6    D 12     6    E ここで取得する条件として ■テーブルAにあるのは、必ず取得します。 ■テーブルAのキーとテーブルBのキーは繋がり、繋がったテーブルBの情報は  別レコードとして取得します。 ■テーブルAのキー1つに対して、テーブルBのキーは無いかも知れないし、  複数件あるかも知れません。  無い場合はテーブルAの情報のみを出力し、複数件ある場合はその全てを出力します。 ■テーブルBの項目2が同じ値のデータがある場合、テーブルBを出力したレコードと  同じレコードに、項目2が同じデータの情報を出力します。  項目2が同じデータが無い場合はこの情報は出力しません。  項目2が同じ値のデータは最大2件しかありません。 上記の例の場合に出力したい結果 ・出力テーブルC キー  フラグ   項目1  項目2  項目3   項目2が同じキー  項目2が同じ値 10  テーブルA   X 10  テーブルB         5    C 10  テーブルB         6    D        12            E 20  テーブルA   Y (テーブルC のフラグとは、テーブルAの情報かテーブルBの情報かを示します) これを出来ればSQL、出来なければPL/SQLで取得したいのですが どちらの場合でも取得の方法に悩んでいます。 どのような方法で取得できるのでしょうか?

  • SELECT 文 GROUP での1件目を取得

    非常に初歩的な事で恐縮ですが、 以下のデータを抽出するsql文の書き方を模索しています。 環境:SQLSERVER2005 | 列1| 列2 | +---+---+ | 1 | A | | 1 | B | | 1 | C | | 1 | D | | 2 | F | | 2 | G | | 2 | H | | 3 | X | | 3 | Y | | 3 | Z | 上記のテーブルがあるとします。 列1でグループした値で、1レコード目の列2を抽出したいのです。 出力結果としては、 列1列2 +--+--+ 1,A 2,F C,X としたいのです。 列1でGROUPしてしまうと列2の内容を集約しないといけないので困っています。 ご教授いたけないでしょうか?

  • SQLで最新の3件分の統計をとりたい

    お世話になります。 Access2000のSQLを使用しています。 下記のテーブルAから、最新の3件分の結果を取得したいのですが、 どのようにSQLを作成すればよいでしょうか? 誠に勝手ですが、SQL文で回答頂ければ助かります。 ※クエリでも結構ですので教えて頂ければと思います。 以上宜しくお願い致します。 --テーブルA-- 日付  名前 2013/6/1 A 2013/4/1 B 2013/7/1 C 2013/3/1 D --結果B(最新の日付の3つ-- 2013/7/1 C 2013/6/1 A 2013/4/1 B