• ベストアンサー

最大値を含むレコードの抽出

あるテーブルから、最大値を持つレコードのキーと最大値だけでなく、そのレコードの値を出したいと思います。 最大値をもつレコードを抽出して、元のレコードと結合するしか方法はないのかなと思い、類似した質問があるような気もするのですが、条件が異なるとうまく行かないため、自分なりに考えてみました。 データベースはDB2です。 SELECT a.倉庫,a.品目,a.単価 FROM 在庫マスタ as a where (a.品目,a.単価) in (select b.品目, max(b.単価) from 在庫マスタ as b group by b.品目) つまり、副問合せするときの結合キーが複数あるとSQLがエラーになってしまうようなのです。 結合キーが2つ以上ある時、このようなパターンの対処方法は無いでしょうか?

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

  • ベストアンサー
  • CHRONOS_0
  • ベストアンサー率54% (457/838)
回答No.3

SELECT a.倉庫,a.品目,a.単価 FROM 在庫マスタ as a where a.単価 in (select max(b.単価) from 在庫マスタ as b where b.品目=a.品目) でいいんじゃないの

hatsuzo
質問者

お礼

有難うございました。 このようなシンプルな方法で実行できるのですね。 maxを求めるのに、GROUP BYを書かなくてもよい、というのが良く判りませんが、とにかくシンプルで早いですね。

その他の回答 (3)

回答No.4

#2回答者です。 一番簡潔なSQL(#3さん提示のSQL)を思いつかなかった自分が、ちょっと情けないです。 代わりに、もう一つ別のSQLを提示しておきます。 DB2は、分析関数をかなり前から実装しています。分析関数を使えば、ネストの深いサブクエリに比べ、代替手段として使える上に、性能も出すことが可能です。 <例3> SELECT x.倉庫,x.品目,x.単価 FROM (SELECT RANK() OVER(PARTITION BY 品目 ORDER BY 単価 DESC) AS rank, 倉庫,品目,単価 FROM 在庫マスタ) AS x WHERE x.rank=1

hatsuzo
質問者

お礼

有難うございました。 言葉足らずでしたが、自分の使っているのはOS400のDB2なので、 機能が少ないのかもしれません。 OVER句が使えないようです。 再三のご回答有難うございました。

回答No.2

数年前にDB2でのシステム開発支援をしたことがあるのですが、当時のDB2は、行値構成子(行値式)※1を使っての操作に制限がかなりありました。 ※1 「where (列1,列2) 演算子 (値1,値2)」という条件式。 SQL-92で、標準SQLに取り入れられています。 行値構成子を使用しないSQL例を提示しますので、試してみてください。 <例1> SELECT a.倉庫,a.品目,a.単価 FROM 在庫マスタ AS a WHERE EXISTS (SELECT 1 FROM 在庫マスタ AS b WHERE a.品目=b.品目 GROUP BY b.品目 HAVING a.単価=MAX(b.単価)) <例2> SELECT a.倉庫,a.品目,a.単価 FROM 在庫マスタ AS a WHERE a.単価 >= ALL (SELECT b.単価 FROM 在庫マスタ AS b WHERE a.品目=b.品目)

hatsuzo
質問者

お礼

有難うございました。 何れも動作しました。 <例2>のほうが若干スピードは速いようです。 DB2でこのような書き方が出来るとは知りませんでした。

回答No.1

DB2はin述語で複数の要素のあるセットを扱えないのかな? Oracleもそうだったような……DBMSによって方言があるようです。 手元にDBの環境がないので、自信ないけれども…… SELECT a.倉庫,a.品目,a.単価 FROM 在庫マスタ as a where a.品目 in (select b.品目 from 在庫マスタ as b where b.単価 in (select max(c.単価) from 在庫マスタ as c group by c.品目))

hatsuzo
質問者

お礼

有難うございました。 正常に動作するようです。 ただし、副次問合せが多重なので、時間が掛かるようです。

関連するQ&A

  • ACCESS2000 SQL 最大レコード数

    こんにちは。 [TBL] キーは A B DD Cです。 A B DD C E 1 2 21 7 ..... 1 2 21 8 ..... 1 2 22 3 ..... 1 2 22 8 ..... 1 2 22 9 ..... 3 1 2 1 ..... 3 3 4 2 ..... から、A=1 B=2の数の最大レコード数をカウントしたいです。 但し、DDは同じ数なことが条件です。 上でいうと、D=22のものが3つあり、D=21のものが2つあるので、最大は3ということで、3を取得したいです。 select count(*) FROM TBL where A=1 AND B=2 GROUP BY C に近い感じだとはおもうのですが。 よろしくお願い致します。

  • SQLiteで最も古いレコードのみの削除

    AndoroidでDBを使うのですが、考える動作のSQL文が作成できません。 テーブルTESTは以下のカラムを持ちます  ・ID - primary key not null  ・VALUE - not null テーブルTESTは最大で10件のレコードを保持します、11件目のレコードが発生したら 最も古い1件目のレコードを削除してから、11件目のデータを新しい10件目のデータとして テーブルに保存します。 そのために「最も古いレコード1件のみを削除する」というSQLを作成したいのですが、 考えたSQL文が正しくないと怒られてしまいます。 delete from TEST as A, (select * from TEST LIMIT 1)as B where A.ID=B.ID; この動作を1つのSQL文で行うのは不可能なのでしょうか?

  • SQLでレコードの抽出

    MySQLです。 商品IDと販売先、管理番号が、判明しているとき、 最大商品IDとそのレコードを取得するには、 どのようなSQLを書けば、よろしいでしょうか? select *, ? from SYOUHIN WHERE ???? テーブル例) ↓ユニーク 商品ID 販売先 管理番号  販売日 1   A社   1     2015-07-10 2   A社   2     2015-07-12 3   B社   1     2015-06-30 4   B社   2     2015-07-06 5   C社   1     2015-04-21

    • ベストアンサー
    • MySQL
  • GROUP BYの記述方法について

    GROUP BYの記述方法について教えてください --------------------- 受注データ(テーブル) --------------------- 品目CD 受注数 00001  10 00001  10 00002  20 00002  15 --------------------- 品目マスタ(テーブル) --------------------- 品目CD 品目名 00001  えんぴつ 00002  けしごむ 00003  色鉛筆 上記二つのDBから、品目ごとの受注数の合計を取得するときのSQL文として、どうするのが正しいのでしょうか? --------------------- 欲しい結果 --------------------- 品目CD 品目名  受注数 00001 えんぴつ 20 00002 けしごむ 35 (考えられるSQL) CASE1:受注データの品目CDと品目マスタの品目名のグループ化 SELECT A.品目CD, B.品目名, SUM(A.受注数) FROM 受注データ A, 品目マスタ B WHERE A.品目CD = B.品目CD GROUP BY A.品目CD, B.品目名 CASE2:受注データをグループ化した結果と品目マスタを結合 SELECT X.品目CD, X.受注数合計, Y.品目名 FROM  (SELECT 品目CD, SUM(受注数)   FROM 受注データ   GROUP BY 品目CD)X,品目マスタ Y WHERE X.品目CD = Y.品目CD CASE3:品目マスタの品目CDと品目名のグループ化 SELECT B.品目CD, B.品目名, SUM(A.受注数) FROM 受注データ A, 品目マスタ B WHERE A.品目CD = B.品目CD GROUP BY B.品目CD, B.品目名 レスポンスも含めて教えてください。 よろしく、お願いします。

  • 最大値が抽出できない!

    SELECT MAX文で、フィールドの最大値を出しています。 これまで、何の問題もなく動作していたのですが、フィールドの数値が9999を超えたとたん、10000、10001などの数値があっても常に9999を最大値として返してくるようになりました。 どうしてでしょうか? 【説明】 A. 例文は次のようなものです。 SELECT MAX(`idc`) from testinvoice; B. `idc`は長さ13のVARCHERです。整数がLatin1で収納されています。 C. `idc`に収納されているデータは、1580からはじまって、9998、9999、10000、10001まで続く約8500件の連番(整数)です。 D. これまで何年も問題なく最大値を出してきました。 とても不思議です。

    • ベストアンサー
    • MySQL
  • ACCESS 以下のようなレコードを抽出するSQL

    ACCESSのデータベースで あるフィールド(フィールドAとします)の値に対して、 別のフィールド(フィールドBとします)の値が1つに決まる データベースがあるとします。 例えば、フィールドAの値が1のレコードは、 どのレコードもフィールドBの値はaである。など このようなデータベースでこのような関係になっていないレコード 例えば、フィールドAの値が1のレコードの中に フィールドBの値がaであるレコードと フィールドBの値がbであるレコードがある。など を抽出するSQLはどのように記述すればよいでしょうか。 テーブル名はTABEL1とします。 次の2つのケースでお願いします。 (1)フィールドAの値が異なればフィールドBの値が異なる場合 例えば、フィールドAの値が1で、フィールドBの値がaであるレコードが ある時、フィールドAの値が1でないレコードの中には、   フィールドBの値がaであるレコードが存在しない場合   (2)フィールドAの値が異なるがフィールドBの値が同じこともある場合 例えば、フィールドAの値が1で、フィールドBの値がaであるレコードが あっても、フィールドAの値が1でないレコードの中にも、   フィールドBの値がaであるレコードが存在する場合 【回答例】(ただし、1,a,bなどの具体的な値は使わないこと) ・フィールドAの値が1のレコードを表示する例 SELECT * FROM TABLE1 WHERE フィールドA=1; ・フィールドAの値が1でフィールドBの値がaのレコードを表示する例 SELECT * FROM TABLE1 WHERE フィールドA=1 AND フィールドB='a'; ・フィールドAの値が1でフィールドBの値がaのレコードと  フィールドAの値が1でフィールドBの値がbのレコードを表示する例 SELECT * FROM TABLE1 WHERE (フィールドA=1 AND フィールドB='a') OR (フィールドA=1 AND フィールドB='b'); この目的は、データベースに問題があり、 問題となっているレコードを見つけて直したいのです。 よろしくお願いします。

  • テーブル結合について、下記SQLをANSI結合の書き方で表したい。

    テーブル結合について、下記SQLをANSI結合の書き方で表したい。 select * from (select key from A union select key from B union select key from C) X, A,B,C where X.key=A.key(+) and X.key=B.key(+) and X.key=C.key(+) このSQLをANSI結合の記述で書きたいのですが、 (+)での結合文になれておらず試行錯誤しております。 下記のようなのかなとは模索しておりますが、 手元に実行環境がなくわかりません。 また、要所気付く点などありましたら、ご指摘願います。 select A.*, B.*, C.* from (select key from A union select key from B union select key from C) X, LEFT JOIN A ON X.key=A.key LEFT JOIN B ON X.key=B.key LEFT JOIN C ON X.key=C.key

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

    お世話になります。 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 テーブル名 ) ---------------------------------- 但し、上記の場合、 社員ごとに最大値レコードが取得できません。 どなたかレコード取得方法について 教えていただけないでしょうか? よろしくお願いいたします。

  • 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
  • 結合したテーブルに名前をつけるには?

    お世話になります。 【前提】 Aテーブル |key|hoge|int1|int2| (keyはユニーク) Bテーブル |key|hogehoge| (keyはユニーク) 上記のテーブルを、下記のSQLで結合。 SELECT `A`.`key`,(`A`.`int1` / `A`.`int2` ) as `kekka`, `B`.`hogehoge` From `A` left join `B` on `A`.`key` = `B`.`key` 【目的】 ユニークではない`A`.`hoge`の重複を省き、かつ、`kekka`が最大のものを選びたい。 【考え方】 `A`.`hoge`でグループ化し、max(`kekka`)を選ぶ。 【そのために】 SELECT `A`.`key`,(`A`.`int1` / `A`.`int2` ) as `kekka`, `B`.`hogehoge` From `A` left join `B` on `A`.`key` = `B`.`key` IN(SELECT max(`kekka`) FROM `●●` GROUP BY `A`.`hoge`) ★質問です。 1)根本的に足りてない知識は何でしょうか? 2)上記の考え方で間違っていませんか? 3)●●には何を入れればよいでしょうか? (`A`を指定してみましたが、Unknown column 'kekka' in 'field list'といわれてしまいました) MySQLのバージョンは5.1.57です。