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

このQ&Aのポイント
  • テーブル名がshohinであるデータベースには、typeとcreate_dateの2つの列が存在します。
  • テーブルには複数のデータが格納されており、typeごとにカウントされ、create_dateの最新の日付順にソートされた結果を出力したいと考えています。
  • 副問い合わせを使用してこの要件を実現することが可能ですが、Group By後に最新の日付を取得してソートする方法がわからないため、具体的なSQL文が正確にわかりません。
回答を見る
  • ベストアンサー

件数をカウントして日付でソートする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 した結果からさらに最新の日付を取得してソートというのがどうも上手く書けませんでした。 お分りになる方がいらっしゃいましたら、ぜひともご教示願います。

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

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

最新日付の取得はMAX()関数、ソートはORDER BY句を使用すれば出来ます。 http://www.postgresql.jp/document/pg746doc/html/functions-aggregate.html http://www.postgresql.jp/document/pg746doc/html/queries-order.html 例) ----------------------------------------------------- SELECT type, COUNT(*), MAX(create_date) FROM shohin GROUP BY type ORDER BY MAX(create_date) DESC

deka_pink
質問者

お礼

なるほど~。 ORDER BY でMAXを使えるとは知りませんでした。 これは便利ですね。 非常に参考になりました。ありがとうございました。

関連するQ&A

  • 月間集計ですべての日付を抽出するには

    Oracle9iで開発をしております。 月間集計をするにあたり、SQLをどのように書けばよいのか質問させていただきたいと思います。 たとえば、COUNTテーブルというテーブルがあり 年月日 カウント数 2005/09/01 1000 2005/09/01 1000 2005/09/02 2000 2005/09/03 3000 2005/09/05 5000 2005/09/06 6000 というようにデータが入っていたとします。 現在、 SELECT 年月日, SUM(カウント数) FROM COUNTテーブル WHERE COUNT_DATE BETWEEN TO_DATE(to_char(?||'/'||?||'/01')) AND LAST_DAY(TO_DATE(to_char(?||'/'||?||'/01'))) GROUP BY 年月日 としていまして、抽出されるデータは 2005/09/01 2000 2005/09/02 2000 2005/09/03 3000 2005/09/05 5000 2005/09/06 6000 となります。 ここで、2004/09/04や2005/09/07以降2005/09/30までのテーブルには存在 しない日付も抽出したいと思っています。 どのようにすれば抽出できるのでしょうか?

  • ユニークなデータの件数を取り出すSQL文

    下記のようなテーブルから ユニークなデータの件数を取り出すクエリを作成したいのですが、どうもわかりません。 教えてください!宜しくお願い致します。 NO | CD1 | DATE1 | CD2 | DATE2 | CD3 | DATE3 1 111 20120301 222 20130301 333 20130303 2 111 20120301 222 20130301 333 20130303 3 222 20120301 333 20130301 4 222 20120301 333 20130301 5 333 20120301 444 20130301 555 20130302 6 333 20120301 444 20130301 555 20130303 7 333 20120301 8 333 20120302 というテーブルがあって、 この中で DATE1、DATE2、DATE3のいずれかが、 同じであれば、行を取り出しカウントする。 1項目しかデータがなければ、単純にカウントする。 取り出しはCDのみ。 上記であれば、 COUNT | CD1 | CD2 | CD3 2 111 222 333 2 222 333 2 333 444     ※こちらはDATE3が異なるのでCD3は取り出さない。 2 333

  • SQLServerトリガー(データ追加時)

    Microsoft SQL SERVER 2005でデータ更新/追加時に起動するトリガーを 作成したいのですが記述方法がわかりません。 テーブル:TBL_SHOHIN SHOHIN_NAME NVARCHAR(50) /* 商品名 */ SAKUSEI_DATE datetime /* 作成日付 */ KOSHIN_DATE datetime /* 更新日付 */ このTBL_SHOHINテーブルに追加があった時は、作成日付(SAKUSEI_DATE)にシステム日付をセット このTBL_SHOHINテーブルに更新があった時は、更新日付(KOSHIN_DATE)にシステム日付をセット 更新時は下記の記述でうまくいったのですが、追加時をどう記述すればいいの でしょうか? create TRIGGER trgSHOHIN ON TBL_SHOHIN FOR INSERT, UPDATE AS BEGIN UPDATE TBL_SHOHIN SET KOSHIN_DATE = GETDATE() END RETURN

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

    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
  • 1個のSQL分で2種類以上の件数値を取得する

    SQL分の記述で質問なんですが、 データベース上に日付、時間、フラグと言う項目があります。 同一の日付、時間のものは数件ずつあります。 フラグは"b"と"1"があります。 このデータの日付・時間辺りの件数と+フラグが"1"の件数を同時に取得するSQL分はかけますでしょうか? 別々ならば、 SELECT DATE,TIME,COUNT(*) AS KENSU1 FROM W_TABLE GROUP BY DATE,TIME ORDER BY DATE,TIME と SELECT DATE,TIME,COUNT(*) AS KENSU2 FROM W_TABLE WHERE FLG="1" GROUP BY DATE,TIME ORDER BY DATE,TIME でかけると思うのですが、 1個のSQL分で記述は可能でしょうか? 処理結果を 05/02/23 12:00 10 5 05/02/24 10:00 12 3 (日付・時間・件数・フラグ="1"の件数  見たいに取得したいのですが..

  • 検索後のソートについて

    PHP、MySQL、初心者なのですが、現在検索アプリの作成にチャレンジしておる者です。 こちらの過去ログを参考にさせていただいたのですが、どうしても検索後のソートがうまくいきません。 一度検索されたものに対するソートについて http://oshiete1.goo.ne.jp/kotaeru.php3?q=1482358 上記の過去ログを参考に、「create temporary table tmp」の箇所を 自分のサイトに置き換えて試してみたのですがうまくソートができず、 ついに力尽きてしまいました。 静的に表示させた場合、表示された表のヘッダ部分(各名称)をクリックすると、 表示されたものはソートできるようにはなったのですが... $sql = "SELECT * FROM perfume where shohin_name like '%$word%' "; 通常は上記のように検索フォームに入力した語句(変数(word))を受け取って表示させています。 過去ログを参考に $sql = "create temporary table tmp SELECT * FROM perfume where shohin_name like '%$word%' "; としては見たのですがうまくいきません。 どなたか正しいスクリプトの書き方を教えていただけないでしょうか? ご教授、宜しくお願いいたします。

    • ベストアンサー
    • MySQL
  • データの件数を集計するための SQL

    データの件数を集計するための SQL について教えてください。 例えば以下のようなテーブルがあります。 ▼テーブル 名前 |交通手段|日付 -----+--------+---- Aさん|バス |5/1 Aさん|バス |5/2 Aさん|バス |5/3 Bさん|バス |5/1 Bさん|電車 |5/2 ※「日付」については、本質問に直接の関係はありません。 このテーブルにクエリを発行して、以下の結果を取得したいと考えています。 ▼取得したい結果 名前 |交通手段|回数 -----+--------+---- Aさん|バス |3 Bさん|バス |1 Bさん|電車 |1 当方がイメージしている流れは以下の通りです。 SQL は苦手でして、これをひとつにまとめることができません。 1) GROUP BY で束ねる SELECT 名前, 交通手段 FROM テーブル GROUP BY 名前, 交通手段 2) 1)の結果の1件目をSELECTする SELECT COUNT(*) FROM テーブル WHERE 名前='Aさん' AND 交通手段='バス' 3) 1)の結果の2件目をSELECTする SELECT COUNT(*) FROM テーブル WHERE 名前='Bさん' AND 交通手段='バス' 4) 1)の結果の3件目をSELECTする SELECT COUNT(*) FROM テーブル WHERE 名前='Bさん' AND 交通手段='電車' なおレンタルサーバ上 (MySQL 5.0.77) で稼働させるため、 なるべく高速な SQL を希望いたします。

    • ベストアンサー
    • MySQL
  • SQL内でループさせるような検索文

    以下の(1)のようなデータがあった場合、一つのSQL文で(3)の表が 取得できる方法はございますでしょうか? (1)table T_SAMPLE | UID | FLAG | CREATE_DATE | ------------------------------------------------ | 000 | A | 2009-01-26 00:00:00 |★ | 000 | A | 2009-01-26 00:00:10 | | 000 | B | 2009-01-26 00:00:20 | | 002 | A | 2009-01-26 00:00:05 |★ | 002 | B | 2009-01-26 00:00:13 | | 002 | A | 2009-01-26 00:01:00 | | 002 | B | 2009-01-26 00:02:02 | | 003 | B | 2009-01-26 00:05:00 |★ | 004 | B | 2009-01-26 00:00:00 |★ | 004 | B | 2009-01-26 00:00:15 | | 004 | A | 2009-01-26 01:00:00 | | 005 | B | 2009-01-26 00:00:11 |★ | 005 | B | 2009-01-26 00:04:05 | (2)同じUIDがあった場合、CREATE_DATEが早い情報(上表★)を使用 | UID | FLAG | CREATE_DATE | --------------------------------------------------- | 000 | A | 2009-01-26 00:00:00 |★ | 002 | A | 2009-01-26 00:00:05 |★ | 003 | B | 2009-01-26 00:05:00 |★ | 004 | B | 2009-01-26 00:00:00 |★ | 005 | B | 2009-01-26 00:00:11 |★ (3)FLAGでカウント <= 取得したい結果 | COUNT(FLAG) | FLAG | -------------------------------- | 2 | A | | 3 | B | イメージとしては、 [処理a] select FLAG from T_SAMPLE where UID = '000' order by CREATE_DATE limit 0,1 ×それぞれUID とすると、上記(1)→(2)で select UID,[処理aの結果においてUIDに対応したFLAG] from T_SAMPLE group by UID という状態の結果が一度のSQLで取得できればよいと考えているのですが。 実際にこの処理を実施する際は、自由に指定されるCREATE_DATEの範囲で絞り込むため、別テーブルを作って、、、等の処理は避けたいのです。 最適な方法がございましたら、なにとぞご教示願います。

    • ベストアンサー
    • MySQL
  • MySQL4でViewの代わりにできますか?

    PostgreSQLで下記のようなビューを作成し、そのビューから日付でgroupbyして日付ごとのユニーク件数を取っていました。 ---------------------------------------------- create view v_uniqcountday as select substring(datetime, 1, 8) as date, uniqid, careercd, count(*) as cnt from accesslog group by date, uniqid, careercd order by date; select date, count(*) as cnt from v_uniqcountday where (date >= xxx) and (date < xxx) group by date; ---------------------------------------------- しかし、MySQLではViewは作成できないようです。 そこでselect文のみで上記のような集計は可能でしょうか? よろしくお願いいたします。

  • SQL(oracle)での並べ替え

    SQL(oracle)での並べ替えで質問がございます。 TABLE:AAA NO, NAM,GNo, DATE ------------------ 1, abc, 3, 09/01 2, bcd, 2, 08/25 3, cde, 2, 08/23 4, def, 3, 09/05 5, efg, 1, 09/03 6, fgh, 3, 08/21 のようなテーブルがあったときに、下記条件で並べ替えを したいと思っています。 1.GNo毎に最小のDATEを抽出し、各Gnoの最小のDATEのうち   小さいGNoのグループでソート。 2.1で同一GNo内ではDATEが小さい順にソート。 つまり、上記の例では、各GNoの最小のDATEは、 1・・・09/03 2・・・08/23 3・・・08/21 なので、これからDATEの小さい順に、GNoが 3、2、1の順にソートをします。各GNo毎にもDATEが小さい順に ソートをするので、結果として、 NO, NAM,GNo, DATE ------------------ 6, fgh, 3, 08/21 1, abc, 3, 09/01 4, def, 3, 09/05 3, cde, 2, 08/23 2, bcd, 2, 08/25 5, efg, 1, 09/03 のような順番にしたいのです。この結果のようにするには、 どのようなSQLにすればよいでしょうか? よろしくお願いいたします。