• ベストアンサー

ソートしてからグループ化したいけれど・・・。

SQL構文について質問させて下さい。 ABC │ID │DATE ------------------ XXX │aaa │02/01 YYY │bbb │02/02 YYY │aaa │02/03 と言うデータから、DATEが新しい(大きい)値を抽出し、 次に重複するIDを排除した結果を出したいです。 希望の検索結果は、 ABC │ID │DATE ------------------ YYY │bbb │02/02 YYY │aaa │02/03 となって欲しいのです。 単純にソートした後でIDでグループ化したいのですが、当然できなく、私の考えでは、 SELECT abc, id, max( date ) FROM `test` GROUP BY id ORDER BY date DESC なのですが結果は、 ABC │ID │DATE ------------------ YYY │bbb │02/02 XXX │aaa │02/03 と言う風になり、何故か、2行目の様にDATEに対して、ABCの値が別の行の ID:aaaの値になってしまってます。 どうしたら良いのでしょうか?

  • MySQL
  • 回答数2
  • ありがとう数2

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

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

MySQLのバージョンにもよりますがこんな感じで しょうか。 1度、IDとMAX(`DATE`)を確定させてから、 それをキーに自分自身を検索する感じです。 二回目のORDER BY はダブりがあった場合それを とるおまじないです。 CREATE TEMPORARY TABLE `tmp` SELECT `ID`,MAX(`DATE`) AS `DATE` FROM `test` GROUP BY `ID`; SELECT `test`.* FROM `test` INNER JOIN `tmp` on `test`.`DATE`=`tmp`.`DATE` AND `test`.`ID`=`tmp`.`ID` GROUP BY `ID` ORDER BY `DATE` ASC;

yoshi_drum
質問者

お礼

ご回答ありがとうございます。 なるほど、一時テーブルを作成するのですね。 この方法は思いつきませんでした・・・。 無事、この方法で出来る事を確認しました。 ありがとうございました。

その他の回答 (1)

回答No.2

バージョンが4.1以降で、サブクエリが 使用OKなら select a.abc,b.id,b.maxdate from test a inner join (select id,max(date) as maxdate from test group by id order by date de sc) b on (a.id=b.id and a.date=b.maxdate); これでいけないでしょうか?

yoshi_drum
質問者

お礼

ご回答ありがとうございます。 すみません。バージョンをご報告してませんでした。 バージョンは4.0を使ってるんです。 私もサブクエリで作ってみたのですが、 まったくできませんでした。 サブクエリは4.1からだったんですね・・・。 とても勉強になりました。

関連するQ&A

  • GROUP BYで集約されるときのソートを変えたい

    GROUP BYで集約されるときのソートを変えたい MySQLの5.1を使用しています。 テーブル"tbl"には、"no","id","score"の3つのフィールドがあり、 "no"は主キーです。 +---+----+-------+ | no | id | score | +---+----+-------+ | 1 | 10 | 10002 | | 2 | 10 | 10000 | | 3 | 10 | 10008 | | 4 | 11 | 10004 | | 5 | 12 | 10006 | +---+----+-------+ 上記の表から、 scoreの値が高い順にグループ化してソートしたいのですが、 以下のSQL文ではscoreが最初に登録されたものに集約されてからグループ化されてソートしてしまうため、 思い通りの結果が得られずに困っています。 ↓具体例 SELECT no, id, score FROM tbl ORDER BY score DESC GROUP BY id; +---+----+-------+ | no | id | score | +---+----+-------+ | 5 | 12 | 10006 | | 4 | 11 | 10004 | | 1 | 10 | 10002 | +---+----+-------+ ↓欲しいソート順 +---+----+-------+ | no | id | score | +---+----+-------+ | 3 | 10 | 10008 | | 5 | 12 | 10006 | | 4 | 11 | 10004 | +---+----+-------+ テンポラリテーブルはなるべく使用せずソートしたいのですが、 このような事は可能なのでしょうか? ご存知の方がいらっしゃいましたら教えていただけると助かります。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • ある項目(数値)に加算したものでソートしたい。

    ある項目(数値)に加算したものでソートしたい。 下のようなテーブルがあります。 そのpointに加算した結果でソートしたいのですが、可能でしょうか? テーブル name  | point ああAAA| 100 ああBBB| 400 いいCCC| 300 ううDDD | 200 おおCCC| 500 ============== ふつうにORDER BY point DESC でソートすると下記のようになります。 おおCCC| 500 ああBBB| 400 いいCCC| 300 ううDDD | 200 ああAAA| 100 ============== そこでpointに加算した結果(dbには反映させず、あくまで表示上のみ) name[ *CCC]にはpointに80%加算 いいCCC 300→540 おおCCC 500→900 ソート結果 おおCCC| 900 いいCCC| 540 ああBBB| 400 ううDDD | 200 ああAAA| 100 ============== このような事は可能でしょうか?

  • 件数をカウントして日付でソートするSQL

    こんなテーブルがあったとして、 テーブル名:shohin ------------------- type:文字列 create_date:日付 こんなデータになっていたとして type| create_date ----+----------- abc | 2004/02/01 abc | 2004/02/02 abc | 2004/02/03 hhh | 2004/01/30 xxx | 2004/01/12 xxx | 2004/01/13 xxx | 2004/01/14 xxx | 2004/01/15 xyz | 2004/01/01 xyz | 2004/01/05 このようなデータを出力したいのですが… (typeで集計して、create_dateの一番新しい日付でソート) type | count | create_date -----+-------+----------- abc | 3 | 2004/02/04 -----+-------+----------- hhh | 1 | 2004/01/30 -----+-------+----------- xxx | 4 | 2004/01/15 -----+-------+----------- xyz | 2 | 2004/01/05 これを一発で書くSQLって可能でしょうか? 副問い合わせを使えば出来るような気がするのですが、Group By した結果からさらに最新の日付を取得してソートというのがどうも上手く書けませんでした。 お分りになる方がいらっしゃいましたら、ぜひともご教示願います。

  • 2つの列を合わせてソートしたい。

    2つの列を合わせてソートしたい。 table名:test 【name】 【area】 【ground】 【bldg】  aaa    3    65.12   84.94  bbb    1    24.6    35.14  ccc    3    112.58  114.5  ddd    2    54     83.14  eee    4    89.25   41  fff     3    74.5    99.10 「ground」と「bldg」はfloat型で、整数と小数点の数値が入っています。 やりたいことは「ground」と「bldg」の2つの列で数値が大きい順でソートしたい。 SELECT * FROM `test` ORDER BY `ground` DESC,`bldg` DESC; こうすると、当たり前な話ですが、「ground」でソートされた後に「bldg」でソートされてしまいます。 そうではなくて、「ground」と「bldg」を合わせて、ソートしたいのです。 【求める実行結果】 【name】 【area】 【ground】 【bldg】  ccc    3    112.58  114.5  fff     3    74.5    99.10  eee    4    89.25   41  aaa    3    65.12   84.94  ddd    2    54     83.14  bbb    1    24.6    35.14 色々と試してみましたが、うまくいかず前に進まない状態です。 何かいい解決法をご存知の方がいらっしゃいましたらご教授お願い致します。

    • ベストアンサー
    • MySQL
  • グループ化したあとソートしたい

    MySQL4.1(Windows)での質問です。 以下のようなテーブルのA列をグループ化して、そのcount(A)の値でソートしたいのですが、エラーになってしまい、実行できません。どうすれば良いでしょうか? テーブル A|B ----- 0|aaa 1|bbb 2|ccc 1|ddd 1|eee 0|fff クエリ select A,count(A) from table group by A order by count(A) 表示させたいデータ A|count(A) ---------- 1|3 0|2 2|1

    • ベストアンサー
    • MySQL
  • group by のソート

    mysql Client API version 3.23.49 PHP/4.4.5 で動作させようと思っています。 table a   b 1   2 3   4 2   4 7   1 2   6 1   6 上のデータから以下のような結果を得たいのですが table a   b  idcount1 1   6    2 3   4    1 2   6    2 7   1    1 グループで集計をとり、その上でbに6がある場合は6その他は bの値にNULLもしくは別の値が入るという形でいいのですが・・・ できません。 SELECT a, b, count( * ) AS idcount1 FROM table GROUP BY a するとはじめに読みこんだ値がbには入ってしまいます。 結果 table a   b  idcount1 1   2    2 3   4    1 2   4    2 7   1    1 SELECT a, b, count( * ) AS idcount1 FROM table where b=6 GROUP BY a するとbの値ははじきますし、カウントしている意味がなくなります。 結果 table a   b  idcount1 1   6    1 2   6    1 GROUP BY 処理前のソートを考え、from table後に oder by b=6 asc を使ったがエラー 末尾に oder by b=6 asc を使うと最初に試した値をソートするだけでした。 宜しくお願いいたします。

    • ベストアンサー
    • MySQL
  • SQLについての質問です

    SQLの質問です。(Oracle) 二つのテーブル T1, T2 に、それぞれ三つのカラム A, B, C があり、A, B の値が同じである行においてT1のCからT2のCへ値をコピーするSQLを教えてほしいです。 以下、そのデータ例です。 テーブル T1 A B C --------- 1 AAA 10 2 BBB 20 3 CCC 30 テーブル T2 A B C --------- 1 AAA 0 2 XXX 0 4 YYY 0 この場合、結果としてテーブル T2は1行目だけがカラム Cの値がT1からコピーされ A B C --------- 1 AAA 10 2 XXX 0 4 YYY 0 としたいです。

  • GROUP BY句の使用方法について(初歩的)

    GROUP BY句の使用方法について質問させて下さい。 ■使用するテーブル  ID   日付 ----------------------  AAA   2007-04-01  AAA   2007-04-01  AAA   2007-04-02  AAA   2007-04-03  BBB   2007-04-01  BBB   2007-04-03  CCC   2007-04-02  CCC   2007-04-02  CCC   2007-04-02 ■抽出したいこと  ID毎のカウントを取りたいのですが、その際に同じ日付は1回のカウントとして抽出したいのです。  即ち、下記の結果を得るのが目的ですが、どのようなクエリとすればいいでしょうか?  ID  cnout(*) ----------------------  AAA   3  BBB   2  CCC   1 初歩的な質問なのですが、宜しくお願い致します。 (※環境はSQL-Server2000です)

  • GROUP BY句の集計について

    はじめまして。 いろいろ調べて、何度試しても思うように 結果がでなかったので、投稿させて頂きました。 グループの集計をしてるのですが、 何個のグループがあるのかカウントしたいのです。 aaa bbb 110 a 110 b 111 c 112 d というDBに select aaa, bbb, count(*) as cnt from database GROUP BY aaa ORDER BY aaa だとそのグループ内の該当レコード数がカウントされてしまいます。 上記の例だとグループ数が“3”と結果を返すようにしたいのです。 では。宜しくお願いします。

    • ベストアンサー
    • MySQL
  • GROUP BY使用時のソートについて

    OracleSqlにて「GROUP BY」使用した日付のデータを取得するSql文を作成したのですが、 「ORDER by」句に「DESC」を付けても降順ソートが行えません。 作成したSql文は以下の通りなのですがなぜ降順ソートが行えないのでしょうか? 「GROUP BY」を使用するとソート出来ないと言うことなのでしょうか? それとも日付型なのでソートが出来ないと言うことなのでしょうか? どなたかご存知の方おりましたらご教授下さい。 ------------------------------------------------- SELECT TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY FROM STOCKTBL WHERE TO_CHAR(RECORDDATE,'YYYY/MM/DD')<='2002/03/07' AND TO_CHAR(RECORDDATE,'YYYY/MM/DD')>='2002/02/22' GROUP BY TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY ORDER by TO_CHAR(RECORDDATE,'YYYY/MM/DD') ,RECORDYEAR ,RECORDMONTH ,RECORDDAY DESC -------------------------------------------------