• ベストアンサー

レコードの最大値

いつもお世話になっております。 以下のテーブル(tableA)があるとします。 uid |ym |g_code|ig_code|comment 10001|200804|1 |1 |コメント1 10001|200805|1 |1 |コメント2 10002|200804|1 |1 |コメント22 10002|200805|1 |1 |コメント11 以下のSQLを発行します。 select *, MAX(ym) from tableA where uid='10001' and g_code='1' and ig_code='1' group by g_code, ig_code 取れてくるデータは以下です。 uid |ym |g_code|ig_code|comment |MAX(ym) 10001|200804|1 |1 |コメント1|200805 動作としては以下を期待しています。 uid |ym |g_code|ig_code|comment |MAX(ym) 10001|200805|1 |1 |コメント2|200805 MySQLのバージョンが古いので、サブクエリが使えません。 よろしくご教示お願いいたします。 <環境> MySQL:3.23.58

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

  • ベストアンサー
  • nda23
  • ベストアンサー率54% (777/1415)
回答No.3

以下を試してみてください。 SELECT A.uid,A.ym,A.g_code,A.ig_code,A.comment,MAX(A.ym) FROM tableA A, tableA B WHERE A.uid='10001' AND A.g_code='1' AND A.ig_code='1' AND A.uid=B.uid AND A.g_code=B.g_code AND A.ig_code=B.ig_code AND A.ym<=B.ym GROUP BY A.uid,A.ym,A.g_code,A.ig_code,A.comment HAVING COUNT(B.uid) = 1 (1)tableAとtableAをJOINします。主の方をA、従の方をBとします。 (2)AにとってBは「uid、g_code、ig_codeが等しく、ymが等しいか大きい」ものです。 (3)もし、Aのymが最大なら、B側には等しいものが1個しかありません。  Aのymが最大未満ならB側には等しいものと、大きいもので、2個以上あります。 (4)そこで、HAVING句により、B側が1レコードのものを抽出します。  つまり、それがymが最大値のレコードです。 但し、対象レコードが多数ある場合は処理が遅くなるので、No.1の方の 示したように一時テーブルの使用も視野に入れてください。 あと、集計クエリで、*を使うのはチョット気持ち悪い。また、グループ化の 指定をしていない項目は集計関数を使うべきです。 この理屈から、uid~commentまでをグループ化指定しています。

wonder_dct
質問者

補足

nda23 さんご回答ありがとうございます。 select * from tableA where uid='10001' and g_code='1' and ig_code='1' group by uid, ym, g_code, ig_code order by ym DESC limit 0, 1 上記クエリで期待していたレコードが取得できました。 ありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (2)

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

あ、若干読み違えてました・・・ いずれにしろテンポラリをつかってこんなかんじ create temporary table temp select uid, g_code,ig_code,MAX(ym) as max_ym from tableA where uid='10001' and g_code='1' and ig_code='1' group by uid,g_code,ig_code; select tableA.*,max_ym from tableA inner join temp on max_ym=ym and tableA.uid=temp.uid and tableA.ig_code=temp.ig_code and tableA.g_code=temp.g_code; もし、ほんとに「uid,ym,g_code,ig_code」の4つのキーでユニークな レコードが確定できるならいけると思います。

全文を見る
すると、全ての回答が全文表示されます。
  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

こんな感じでやります。 create temporary table temp select MAX(ym) as max_ym from tableA ; select * from tableA inner join temp on max_ym=ym order by uid asc limit 1; MAX値を取る値が2つあるのを何を基準に優先するのでしょうか? 今回は一応uidの若い方をとりましたが、tableAのuidは見た感じ ユニークな値ではないようですので行き当たりばったりみたいで 気持ち悪いですね・・・ プライマリーキーの設定など仕様をきちんと考えたほうがいいですよ。

wonder_dct
質問者

補足

yambejp さんご回答ありがとうございます。 テーブルを生成するのでしょうか? キーの設定は以下4でしております。 uid ym g_code ig_code

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 最大値を求めたいのですが・・・

    初めまして。 SQL初心者でわからないことが多くて困っています。 求めたいのは、最も労働時間が長い人の労働時間を表示させる ということです。 以下が自分なりにつくったものです。 SELECT SCODE , NAME , MAX(TIME) FROM (SELECT TAR SCODE , MAX(NAME) NAME , SUM(WORK_TIME) TIME FROM NIP , MTOR WHERE NIP.TOR = MTOR.CODE AND DDATE BETWEEN '2008/04/21' AND '2008/05/20' GROUP BY TAR) サブクエリでは4/21~5/20までで、社員ごとに何時間働いたかを出力したものです。 TARが社員コード、NAMEが社員名、WORK_TIMEが一日の労働時間です。 これは以前作ったものなのでそのまま活かせないかと思ってサブクエリとして使っています。 そして、このサブクエリから出力した労働時間のなかから最大値をMAX(TIME)で表示させたのですが、当然、SCODEとNAMEは「GROUP BY の式ではありません」と怒られてしまいます。かといってこれらにMAX()関数を用いても、ただ単に社員コードが最大のものが表示されるだけで、労働時間が最大の人のコードと社員名が表示されません。 何かいい方法はありませんか? 長文で大変申し訳ないです・・・

  • MySQLで、日付最大のレコード抽出

    MySQLをJAVAで使っています。 指定キーの中で、一番日付の大きなレコード項目全てを 取り出したいのですが、 下記SQLだと、何も抽出されません。 (今朝、ここで教えて頂いたSQL文です) 何が間違っているのでしょうか? さらに、もっと簡単なSQL文はないでしょうか? SELECT * FROM food WHERE (food_id = 1) AND (food_name = 'みかん') AND (karute_id = (SELECT MAX(date) FROM food WHERE (food_id = 1) AND (food_name = 'みかん'))) 与える検索キー項目は、food_id=1, food_name=みかん foodテーブル例 food_id  food_name   date --------------------------------- 1     みかん    2015-01-01 1     みかん    2015-02-01 1     みかん    null 1     みかん    2015-04-01 2     きんめだい  2015-01-01 2     じんたん   2015-02-01 2     コロッケ   2015-02-01

    • ベストアンサー
    • MySQL
  • MySQLで、日付最大のレコード抽出

    MySQLをJAVAで使っています。 指定キーの中で、一番日付の大きなレコード項目全てを 取り出したいのですが、 下記SQLだと、何も抽出されません。 何が間違っているのでしょうか? さらに、もっと簡単なSQL文はないでしょうか? SELECT * FROM food WHERE (food_id = 1) AND (food_name = 'みかん') AND (food_id = (SELECT MAX(date) FROM food WHERE (food_id = 1) AND (food_name = 'みかん'))) 与える検索キー項目は、food_id=1, food_name=みかん foodテーブル例 food_id  food_name   date --------------------------------- 1     みかん    2015-01-01 1     みかん    2015-02-01 1     みかん    null 1     みかん    2015-04-01 2     きんめだい  2015-01-01 2     じんたん   2015-02-01 2     コロッケ   2015-02-01

    • ベストアンサー
    • MySQL
  • 一定以上の行があれば最大値を持つ行を削除するSQL

    MySQL5にて、あるテーブルの特定フィールドの数(つまりcount値)が一定値以上であれば、間引きのため別のフィールドの値で最大値をもつ行を削除するSQLを考案中です。 イメージとしては以下の通りですが、SQLとしては誤っており、また、冗長です。 DELETE FROM table WHERE id={$id} AND (SELECT COUNT(*) FROM table WHERE id={$id}) > 5 AND begin = (SELECT MAX(begin) FROM table WHERE id={$id}); よい知恵をお授けください。

    • ベストアンサー
    • MySQL
  • 一つのSQLで実行できるでしょうか?

    sqliteで質問です。 今、以下のようなテーブル(table1)があったとします。 uid | date | comment 010 | 1211 | AAAAA 011 | 1211 | BBBBB 010 | 1220 | CCCCCC 011 | 1220 | DDDDDD このとき、1行目と4行目を取得や削除するようなSQLを一つで記述することは可能でしょうか? イメージてきには、 select * from table1 where {((uid = 010) and (date = 1211)), ((uid = 011) and (date = 1220))} みたいな感じにです。 つまり、where句の組み合わせを複数書いて一つのSQLで実行したいのです。 恐れ入りますが、よろしくお願いします。

  • サブクエリを使わずに実現したのですが。。。

    現在、Mysql 4.0xを利用してDBを構築しています。 しかしながら、サブクエリが使えないため以下のようなクエリが実現できず困っております。 EX: select mg.*,sumlg.* from mg left join (select id,uid from lg where uid = '00001') as sumlg on mg.id = sumlg.id where sumlg.id is null; 上記SQLは特定のユーザーIDの、テーブルBに存在しないテーブルAのIDをユーザー単位で切り分け抽出するSQL文です。 (テーブルBにはIDとUIDでユニークになるレコードが格納されています。) 上記を実現するためのSQLをどなたかアドバイスください。 どうぞよろしくお願いします。

    • ベストアンサー
    • MySQL
  • PDOのデータ取得方法について

    お世話になります。 以前まで「mysql_query」でSQLを実行していたのをPDOで行うように変更しております。 prepareの「?」の部分までのSQLにした場合(1)、データ取得出来ますが (2)ですとエラーも返ってこなくデータ取得出来ません。 色々と試してはいますが、全く出来なくて大変困っています。どうかご教示くださいませ。 1)SELECT * FROM table WHERE data_code = ? and data_code2 = ? 2)SELECT * FROM table WHERE data_code = ? and data_code2 = ? and (data_code3 = "null" or data_code3 is null or data_code3 = "") ※PHP5.3、MySQL5.0です。

    • 締切済み
    • PHP
  • sql文の中での時間取得

    sql文の中で以下のように時間を指定してselectしています。ですが、時間を「sqlの実行時間からn分前までの間」に修正したいと考えています。どなたかご教示いただけませんでしょうか。 select count(*) from tableA where hoge = '0000' and end_time >= cast('2000/1/01 00:00' as timestamp) and end_time < cast('2011/1/31 00:00' as timestamp) たとえば select count(*) from tableA where hoge = '0000' and end_time >= sqlを実施した時間から45分前 and end_time < sqlを実施した時間 のようにしたいです。 ご協力お願い致します。

  • 日付の最大値レコードを取得する方法について

    お世話になります。 SQLで日付の最大値を取得する方法です。 テーブルのデータ内容は以下のようになっています。 | 社員番号 | 社員名 | 日付 | 順序 | +---------+-------+-----------+-----+ | 100 | AAA | 2011/05/01 | 2 |   ← このレコードを取得したい +---------+-------+-----------+-----+ | 100 | AAA | 2011/05/01 | 1 | +---------+-------+-----------+-----+ | 100 | AAA | 2011/04/01 | 1 | +---------+-------+-----------+-----+ | 200 | BBB | 2011/04/01 | 2 |   ← このレコードを取得したい +---------+-------+-----------+-----+ | 200 | BBB | 2011/04/01 | 1 | +---------+-------+-----------+-----+ 取得したいレコードは、 社員ごとの最大日付の最大順序をもつレコードです。 (上記の1行目と4行目のレコードを取得したい) この場合、 下記のようなSQLを考えます。 --------------------------------- SELECT 社員番号, 社員名, 日付 FROM テーブル名 WHERE 社員番号 = 'xxx' AND 日付 = (SELECT MAX(日付) FROM テーブル名 ) AND 順序 = (SELECT MAX(順序) FROM テーブル名 ) ---------------------------------- 但し、上記の場合、 社員ごとに最大値レコードが取得できません。 どなたかレコード取得方法について 教えていただけないでしょうか? よろしくお願いいたします。

  • 副問合せの書き方について

    実行したい内容は、『同一ナンバー内で1番IDが低いコードNOが2のタイトルを出す』といった内容になります。 以下のように書いて実行したところ、『EXISTSを使わないサブクエリでは、サブクエリの選択リストには、式を1つだけしか使えません。と表示されました。』自身のSQL文に問題があるかもしれませんが、現状は下記のSQL文となっています。 "SELECT id, code, num, title FROM contents WHERE code=2 AND id IN (SELECT MIN(id), num FROM contents GROUP BY num)" 副問合せで、同一ナンバーで1番IDが低いIDを取得し、取得したIDをもとに タイトルを出そうとしました。 どなたか御指導御願い願えませんでしょうか。 宜しく御願いいたします。