SQL MAX関数を使用したデータの抽出方法

このQ&Aのポイント
  • SQLのMAX関数を使用して、各品番ごとの最新日付のデータを抽出する方法を教えてください。
  • 過去に同様の質問をしましたが、解決できずに困っています。お力をお貸しいただけると助かります。
  • 抽出したいデータは、ID、品番、金額、日付の情報で、各品番について最新日付のデータのみを表示したいです。
回答を見る
  • ベストアンサー

SQL MAX関数を検索条件にする。

SQL MAX関数を検索条件にする。 わかる方がいれば助けてください。 下記のようなデータのテーブルあります。   ID        品番      金額          日付 OUTLET 210   00182-1080   5600         20090915 OUTLET 214  00182-1080   5600         20090916 OUTLET 217  00182-1080   5600         20090917 OUTLET 50  00182-1080   5600         20090609 OUTLET 437  00191-1082   3300         20100305 BLK09SS703  00191-1082   5500         20090703 OUTLET 141  00191-1082   5500         20090717 OUTLET 170  00191-1082   5500         20090806 このテーブルデータの各品番について最新日付のデータのみを出力したいのですが、 方法がわかりません。group byでHAVING検索なども試しましたがうまくいきませんでした。 <抽出したいデータ>   ID        品番      金額          日付 OUTLET 217  00182-1080   5600         20090917 OUTLET 437  00191-1082   3300         20100305 どなたかお願いします。 前にも同じような質問をさせていただきましたが、 解決できずにこまっています。

  • Oracle
  • 回答数2
  • ありがとう数24

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

  • ベストアンサー
回答No.1

下記のSQL文を参照してください。 SELECT TB1.ID , TB1.HINBAN , -- 品番(HINBAN) [ VARCHAR2(20) NULL ] TB1.KINGAKU , -- 金額(KINGAKU) [ NUMBER(7,0) NULL ] TB1.HIZUKE -- 日付(HIZUKE) [ VARCHAR2(8) NULL ] FROM TEST_TABLE TB1 INNER JOIN( SELECT HINBAN , -- 品番(HINBAN) [ VARCHAR2(20) NULL ] MAX(HIZUKE) AS HIZUKE -- 日付(HIZUKE) [ VARCHAR2(8) NULL ] FROM TEST_TABLE GROUP BY HINBAN -- 品番(HINBAN) [ VARCHAR2(20) NULL ] ) TB2 ON TB1.HINBAN = TB2.HINBAN -- 品番(HINBAN) [ VARCHAR2(20) NULL ] AND TB1.HIZUKE = TB2.HIZUKE -- 日付(HIZUKE) [ VARCHAR2(8) NULL ] 注:SQL文実行の結果は添付画像を参照してください。

anman0201
質問者

お礼

すいません。 Group Byの存在を忘れてました。 無事解決しました。 ありがとうございます。 

anman0201
質問者

補足

ご回答ありがとうございます。 大変参考になりました。 この方法でできたと思ったんですが、新たに問題が出てきてしまいました。 TB1のレコードで稀に最新日付が同一のものがあり、その品番についてINNERJOINすると あたりまえですがその品番だけ2行抽出されてしまいます。 このような品番が出た場合、金額が安いほうをとってきたいのですが、 なにか方法はありますでしょうか? 品番が重複するようなことはどうしても避けたいのです。 お手数ですがなにかよい方法があれば教えていただきたいです。

その他の回答 (1)

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

相関サブクエリを使っても出来ますね。 テーブルの定義は1の方と同じとして、下記の様になります。 例) -------------------------------------------------- SELECT * FROM TEST_TABLE a WHERE NOT EXISTS ( SELECT 1 FROM TEST_TABLE b WHERE a.HINBAN = b.HINBAN AND a.HIZUKE < b.HIZUKE ) ------------------------------------------------------ 「各品番について最新日付のデータ」は以下の様に読み替えられます。 「『同じ品番でより新しい日付の別のデータ』が無いデータ」 これをSQLで表現していることになります。

参考URL:
http://codezine.jp/article/detail/1076?p=2
anman0201
質問者

お礼

ご回答ありがとうございます。 初めて知る関数です。 なんか便利そうですね。 後学のために頭の中にとどめておきます。 また大変申し訳ないんですが、新たな問題が出てきてしまいました。 補足欄に追記させていただきましたので、 お時間があれば助けていただきたいです。 よろしくお願いします。

関連するQ&A

  • SQL HAVING句?集約関数について

    SQL HAVING句?集約関数について 現在、SQLを書いているのですが、集約関数についてわからないことがあります。 下記のようなテーブルについて   品番    SEC   SUB 倉庫コード 日付 金額 0102A255-**** 100 001 412200 64 20100501 5700 0102A255-**** 100 001 412200 64 20091226 7980 0102A255-**** 100 001 412200 64 20091001 9400 品番をひとつに絞り、かつ最新日付とその金額をもってくるためにはどうしたらいいでしょうか? ようは一番上のレコードのみ抽出したいということです。 どなたかお願いします。

  • SQLでの集計について

    こんにちわ。以下のようなテーブルから条件に見合う合計を出したいと思いSQLを書いてみたのですが、 思った結果になりません。 テーブルA ID1 得意先Cd 営業所Cd 日付 1  001    001  2005/09/01 2  001    002  2005/09/01 3  001    001  2005/09/03 テーブルB ID2 ID1 部署 数量 金額 1  1  01  1  1000 2  1  01  1  1000 3  1  02  1  1000 4  2  01  1  1000 5  2  01  1  1000 6  3  01  1  1000 7  3  01  1  1000 8  3  02  1  1000 [抽出結果] 得意先Cd 営業所Cd 日付  部署 数量(Sum) 金額(Sum) 001    001  2005/09/01 01   2   2000 001    001  2005/09/01 02   1   1000 001    001  2005/09/03 01   2   2000 001    001  2005/09/03 02   1   1000 001    002  2005/09/01 01   2   2000 [SQL] select 得意先Cd,営業所Cd,日付,部署,SUM(数量) As '数量計',SUM(金額) As '金額計' from テーブルA AA Inner join テーブルB BB ON (AA.ID1 = BB.ID1) group by 得意先Cd,営業所Cd,日付,部署,数量,金額 order by 得意先Cd,営業所Cd,日付,部署 このSQLを実行すると、日付、部署共に同じ場合でも数量・金額が合計値となりません。 得意先Cd 営業所Cd 日付  部署 数量 金額 001    001  2005/09/01 01 1  1000 001    001  2005/09/01 01 1  1000 どのように変更を加えれば、上記の「抽出結果」にできるのでしょうか? よろしくお願いいたします。

  • これを抽出するSQLを教えてください

    どういうSQLを書けばこれが実現出来るのか分からないので教えて下さい。 テーブル名 f_table というテーブルがあります。 このテーブルには、f_id,u_id,day(日付)という三つの列があり、下記のようにデータが入っているとします。 f_id  u_id    day   1    1   2007/3/8 2    2   2008/1/2 3    2   2008/1/10 4    1   2007/2/12 このf_tableから、各u_idで一番日付の新しいf_idを抽出する(この表の場合f_idの1と3が抽出される)にはどういうSQLで出来るのでしょうか? ※実際の表ではu_idに入っている数字の種類は1と2だけではなく、もっと沢山あります。 ご回答よろしくお願いします。

  • SQLの範囲指定検索の質問です。

    金額100円~300円 というデータがそれぞれテーブル(test1)のカラムに pay_under:100 pay_limit:300 という形で入っています。 これを検索画面で 金額:「  」 の中に 100から300の値を入れて検索した場合に 上のデータが抽出されるSQLの書き方を教えてください。 例) 金額:「150」→ 抽出 金額:「300」→ 抽出 金額:「60」 → 抽出されない

    • ベストアンサー
    • MySQL
  • SQLでの複数検索条件の書き方を教えて下さい。

    SQLを使うことが初めての、本当にど素人です。 質問の仕方自体おかしいかもしれませんが、どなたか下記条件でデータ抽出するSQLの書き方を教えて下さい。 【抽出条件】 1つの商品購入テーブルから、5月と6月に購入してて、7月と8月に購入していない、東京都と神奈川県在住の方の顧客IDと購入商品すべてを抽出できないでしょうか? カラムは、顧客ID、購入月、顧客都道府県、商品コードとそれぞれ分かれています。 この内容で、ご回答いただけますでしょうか? 何卒よろしくお願いします。

  • SQLのsum関数

    こんにちは。 PostgresのSQLが思うように動いてくれません!! そのIDを持っている人がどのくらいの数を持っているのかを抽出したいのです。 テーブルは下記です。 ********************************************* ★Aテーブル ID  名前  数  場所  日付 0001 みかん 1  冷蔵庫 0901 0001 みかん 4  倉庫  0901 0001 みかん 1  冷蔵庫 0901 0002 いちご 1  部屋  0901 0002 いちご 2  部屋  0801 0003 きのこ 6  倉庫  0901 ★Bテーブル ID  名前 0001 みかん 0002 いちご 0003 きのこ 0004 あいす ********************************************* となっている場合、下記SQLを実行すると select a.ID ,b.名前 ,sum(a.数) as 数 from Aテーブル a,Bテーブル b where a.日付 >= '0901' and a.日付 <= '0901' and a.ID = b.ID group by a.ID ,b.名前, a.数 結果が 0001 みかん 2 0001 みかん 4 0002 いちご 1 0002 いちご 2 となり0001は合計6で出て欲しいのに別々に出てしまいます。 理想では 0001 みかん 6 0002 いちご 3 で出て欲しいです。 たとえばこの場合、場所によってなど出てしまうものでしょうか? これはなぜなのでしょうか? よろしくお願いします。

  • デルファイでのSQL文について

    まだ初心者なのでよく分かりません。SQL文について教えてください。 テーブル名:table1 データ:   コード   日付     種類   備考 (1) 1111   2003/12/11  book  AAA (2) 2222   2003/11/10  pencil BBB (3) 2222   2003/12/10  pencil CCC (4) 2222   2003/12/20  cap   DDD 上のようなデータがあった場合、コードと種類が同じで日付が最新のデータを取りたいのですがSQL文でできるでしょうか? 上の場合だと(1)と(3)と(4)のデータを抽出したいのです。GROUP BYですると備考がとれませんでした。 どうぞよろしくお願いします。   

  • SQLでうまいことビューが作れない

    SQLサーバー2005+マネジメントスタジオでビューを作っています。 以下のデータが存在するときに●のついたデータだけを抽出したいです。 明細IDはユニークとし、明細IDの中で一番日付が新しいものだけを取得したいです。 T-SQLでどのように書けばよいか教えてください。 <データ> 明細ID 日付 111 2010/10/01 111 2010/11/01 111 2010/12/01 ● 222 2010/11/01 ● 333 2010/09/01 333 2010/10/01 ● 444 2010/10/01 444 2010/11/01 444 2010/12/01 ● 555 2010/09/01 ● <出力> 明細ID 日付 111 2010/12/01 ● 222 2010/11/01 ● 333 2010/10/01 ● 444 2010/12/01 ● 555 2010/09/01 ●

  • SQLの条件検索について

    下記のような「果物TBL」というテーブルがあるとします。 果物TBL -------------------------------- ID    名前      値段 - - - - - - - - - - - - - - - - - - - - 01    りんご     150 02    バナナ     250 03    みかん     250 04    ぶどう     300 -------------------------------- また上記のテーブルと全く同じ構成の「果物検索TBL」というテーブルがあるとします。 そのテーブルには、例として下記のような値を入れておきます。 果物検索TBL -------------------------------- ID    名前      値段 - - - - - - - - - - - - - - - - - - - - NULL   りんご     250 NULL   バナナ     NULL -------------------------------- この時、下記のようなSQLだと SELECT DISTINCT 果物TBL.名前 FROM 果物TBL INNER JOIN 果物検索TBL ON (果物TBL.ID = 果物検索TBL.ID AND LEN(果物検索TBL.ID) > 0) OR (果物TBL.名前 = 果物検索TBL.名前 AND LEN(果物検索TBL.名前) > 0) OR (果物TBL.値段 = 果物検索TBL.値段 AND LEN(果物検索TBL.値段) > 0); -------------------------------- 名前 - - - - - - - - - - - - - - - - - - - - バナナ みかん りんご -------------------------------- という結果になります。(名前:りんご・バナナと値段:250のOR検索) その結果を -------------------------------- 名前 - - - - - - - - - - - - - - - - - - - - バナナ -------------------------------- という結果にするにはどうすればいいでしょうか?(名前:りんご・バナナと値段:250のAND検索、バナナのみマッチ) 単純にORをANDにしてもうまくいきませんでした。 動的にSQLを作れれば良いのですが、この構成は変えられないのでNULL値がネックになり分かりません。 教えてください。 また、記載してるSQLよりもっとスマートな書き方があれば教えてください。

  • SQLの結合条件について

    SQLの結合条件について ・table_A ID | ATAI 01 | AAA 01 | XXX 02 | ABC 03 | DEF table_B ID | ATAI 01 | 不要 02 | 必要 03 | 必要 04 | 不要 上記のようなテーブルAとBがあるとします。 やりたいこと 1.テーブルAに存在するIDをBのIDから抽出 2.テーブルAの「ATAI」の値が’AAA’のIDは抽出対象から外す。 ※テーブルAの01IDに’AAA’と’XXX’がありますが、Bの抽出対象から外したい。 2.がうまくいきません。 select B.ID from table_A A,table_B B where A.ID = B.ID 上記のSQLに2.の条件を足して、結果を02と03にしたいです。 ※CASEは使わずにお願いします。