• 締切済み

sql 集計結果の抽出方法を教えてください

金額テーブル(会社名、金額)と詳細テーブル(会社名、日付、金額)があり 金額テーブル A社 100円 詳細テーブル A社 2011/1/1 10円 A社 2011/1/2 10円 A社 2011/1/3 50円 A社 2011/1/4 20円 A社 2011/1/5 10円 A社 2011/1/6 10円 詳細テーブルの金額を一件づつ合計していき、金額テーブルの金額を超えた時の 詳細テーブルの日付を抽出するSQLを教えてください。 上記データの2011/1/5を抽出したいのです。 宜しくお願いします。

みんなの回答

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

> 使用してたDBはDB2です。 > エラーになったのではなく、別の結果が出ていました。 補足、ありがとうございます。 DB2は手元に無いので確認は出来ないのですが、エラーになるならともかく、別の結果になったのはちょっと不思議です。 実行されたSQLの内容とその時のテーブルのデータを補足して頂ければ、何か分かるかもしれません。

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

まず、使用しているDB製品とそのバージョンを補足してもらえますでしょうか? (Oracle, SQLServer, MySQL, Access, etc・・・) DBMSの種類によっても動作が違ってきますので。 > すみません どうもうまく動きませんでした。 > SQL文SUMの実行途中の値とうまく比べていないような感じです。 エラーになったのでしょうか? それとも、期待される結果と違うものが取得されたのでしょうか? > 教えていただいたSQLは SUMの集計途中の値と > 比べているのですか? > データの動きがわかりませんでした。 > よろしければ、SQL文の説明をして頂けないでしょうか。 No.2 の方だとちょっと複雑なので、No.1 の方のSQL(下記)を説明します。 (No.2 にも書きましたが、このSQLは複数の会社が在るとうまくいきませんが) ------------------------------------------------ SELECT 日付 FROM 詳細 d1 INNER JOIN 金額 m ON(d1.会社名 = m.会社名) WHERE (SELECT SUM(金額) FROM 詳細 d2 WHERE d2.日付 <= d1.日付) >= m.金額 ORDER BY 日付 LIMIT 1; ------------------------------------------------ 外側のSELECT、つまり詳細テーブルと金額テーブルの会社名が同じものを結合したもの   ⇒ 「詳細 d1 INNER JOIN 金額 m ON(d1.会社名 = m.会社名)」 の一行一行について、それよりも前の日付の詳細テーブルの金額の合計を求めて、   ⇒ 「SELECT SUM(金額) FROM 詳細 d2 WHERE d2.日付 <= d1.日付」 それが、外側のSELECTの金額テーブルの金額よりも大きなものだけを取出して、 日付順で最初の行だけを取得しています。   ⇒ 「ORDER BY 日付 LIMIT 1」 この様に外側のクエリの値を参照する内側のクエリを相関サブクエリと言います。 詳しくは下記のページなどを参考にして下さい。 http://gihyo.jp/dev/serial/01/sql_academy2/000901 http://gihyo.jp/dev/serial/01/sql_academy2/000902 http://gihyo.jp/dev/serial/01/sql_academy2/000903 http://gihyo.jp/dev/serial/01/sql_academy2/000904 https://codezine.jp/article/detail/460?p=1 http://www.techscore.com/tech/sql/07_01.html#sql75

710hide
質問者

お礼

返信がおそくなりすみませんでした。 説明ありがとうございました。 使用してたDBはDB2です。 エラーになったのではなく、別の結果が出ていました。

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

訂正です。 #1 のSQLでは、複数の会社が在る場合にうまくいきませんね。 会社ごとにグループ化してやる必要が有りました。 ---------------------------------------------------- SELECT d1.company, MIN(date) FROM detail d1 INNER JOIN money m ON(d1.company = m.company) WHERE (SELECT SUM(amount) FROM detail d2   WHERE d1.company = d2.company AND d2.date <= d1.date) >= m.amount GROUP BY d1.company; ----------------------------------------------------

710hide
質問者

お礼

ありがとうございました。 このSQLを参考にして実行してみます。 お世話になりました。

710hide
質問者

補足

すみません どうもうまく動きませんでした。 SQL文SUMの実行途中の値とうまく比べていないような感じです。 SQL初心者なのですが、データを一件づつ合計していくイメージがわかりません。 教えていただいたSQLは SUMの集計途中の値と比べているのですか? データの動きがわかりませんでした。 よろしければ、SQL文の説明をして頂けないでしょうか。

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

2011/1/5は金額テーブルの金額と同じになった時ですよね? 金額テーブルの金額を超えた時だと2011/1/6になるかと。 抽出は相関サブクエリを使えば可能です。 詳細テーブルの金額の合計が金額テーブルの金額以上になった日とすると、下記の様になるかと。 どのDB製品が対象か分かりませんので、なるべく標準SQLに沿うように書きました。 ------------------------------------------------- SELECT 日付 FROM 詳細 d1 INNER JOIN 金額 m ON(d1.会社名 = m.会社名) WHERE (SELECT SUM(金額) FROM 詳細 d2 WHERE d2.日付 <= d1.日付) >= m.金額 ORDER BY 日付 LIMIT 1; ------------------------------------------------- WHERE 句は詳細テーブルのある日付の以前の金額の合計が金額テーブルの金額以上である条件を表しています。 金額テーブルの金額も結合を使わずにWHERE句内の相関サブクエリで取得することも出来ます。 金額テーブルの金額を超えた時を抽出する場合は「>=」の部分を「>」にして下さい。

参考URL:
http://codezine.jp/article/detail/907

関連するQ&A

  • 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 の抽出方法

    あるテーブルABC に項目aとbとc があるとします。 今、抽出の条件が 仮にa=1,b=2 として、 この条件で複数件のデータが抽出され その中からcが最大のデータ1件のみを抽出するとします。 このSQLを作成する場合、 どのような方法がありますでしょうか? select文で、1度cのmax値を求めないといけないでしょうか?

  • これを抽出する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サーバにある日付型のデータから特定の曜日を抽出する方法は?

    SQLサーバに日付と料金の入ったテーブルがあります。 例えば、下のようなデータがあるとします。 日付            料金 2005/11/08 11:15:00  5000円 2005/11/09 12:00:00  6000円 2005/11/15 15:15:00  4000円 2005/11/16 09:00:00  7000円 このテーブルから火曜日のデータだけを抽出したい場合、 どのようなSQL文を書けばよいのでしょうか? どうぞ、よろしくお願いしますm(_ _)m

  • アクセスで抽出+合計

    アクセス2003を使用しているんですが、 どうしてもわからないので教えてください。 アクセスのテーブルで 会社名1 会社名2   金額1   金額2       A社    B社    5000    4000 B社    C社    2500    1000 C社    D社    7000    4500 とこんな感じにデータがあります。 会社名・金額はそれぞれ5つ設けてあります。 わけがあり、別々に列を設けるしかありません。 このテーブルから、たとえばB社の金額の合計を 出してきたいのですが。 この表ですと、B社 6500  と表示させたいのです。 B社だけではなく、全会社いっせいにあらわしたいのです。 可能なのでしょうか? SQLでもかまいません。 お願いいたします。

  • SQL 集計について

    集計方法がどうしてもわからないのでご教授ください。 下記のテーブルを持っています。 テーブル1では日々の売上金額を管理し、 テーブル2では一週間の日付が保存されています。(月曜日~日曜日) -------テーブル1-------           日付    売上金額   2013/09/01     3000   2013/09/02     4000   2013/09/03     2000    ・              ・           ・           2013/09/30     1000 ----------------------- --------テーブル2---------  日付(月)    日付(日)    2013/08/26   2013/09/01 2013/09/02   2013/09/08    ・        ・    ・       2013/09/30   2013/10/06 ------------------------- テーブル1とテーブル2の情報をもとに テーブル3にある、日付(月)と日付(日)は、テーブル2から持ってきて、 一週間の集計を行いたいと思っております。 --------------テーブル3--------------  日付(月)    日付(日)    売上金額 2013/08/26  2013/09/01     3000 2013/09/02  2013/09/08     6000   ・   ・   ・ 2013/09/30  2013/10/06     1000 ------------------------------------ このようにするにはどのようなSQLを組めばいいのでしょうか? SQL初心者のため、難しい単語などを使わずに ご説明をしていただければと思います。 どうぞ、よろしくお願いいたします。

  • SQLの抽出条件の記述の仕方について

    sqlのselect ~where等で以下のデータが抽出できますでしょうか。 テーブルに以下のデータが格納されています。 県コード  コード 商品名        単価 ------------------------------------------------------------ 01      1000 カメラ(中国製)   10,000円 01     2000 カメラ(日本製)   30,000円   01      3000 カメラ(アメリカ製) 40,000円 ------------------------------------------------------------ 02      1000 カメラ(中国製)   10,000円 02      3000 カメラ(アメリカ製) 40,000円 ------------------------------------------------------------ 上記のようなデータのなから、一つの県から、1つの商品(コード:2000(カメラ(日本製))、3000(カメラ(アメリカ製))、1000(カメラ(中国製))の優先順位で1つを選択)をselect文で抽出可能でしょうか。上記のデータならば、以下のデータを抽出したいのですが。 01     2000 カメラ(日本製)   30,000円 02      3000 カメラ(アメリカ製) 40,000円 2件のみを抽出できますか。

  • ACCESS2000のSQLについて

    ACCESS2000のSQL文について質問です。 K情報テーブル:(支店(テキスト型),所属(テキスト),氏名(テキスト),ログ(テキスト),抽出件数(数値),処理日(日付型)) 支店 所属 氏名 ログ 抽出件数 処理日 ----------------------------------------- 関東 埼玉 太郎 A   50    2009/02/25 関西 大阪 次郎 B   15    2009/04/01 関東 埼玉 太郎 A   10    2009/03/05 関西 大阪 次郎 B   5    2009/04/06 東北 青森 三郎 C   2    2000/01/02 東北 青森 三郎 A   2    2000/01/02 ・ ・ ・ ----------------------------------------- 以上のテーブル情報を、SQL文にて抽出したいのですが、抽出条件が私には難解で解決の見通しが立ちません。ご教授をお願いします。 ***条件*** [ログ] = "A" のみ抽出。 現在日から過去3ヶ月前までのデータのみ抽出。 [氏名]ごと[ログ]の総合計。 [氏名]ごとの[抽出件数]の総合計。 [ログ]の総合計の上位30件を降順で。 順位にNo.をふる。 上記の条件で抽出したデータをを下記の作業テーブルに出力したと思っております。 作業テーブル:順位,所属,氏名,ログ件数,抽出件数 宜しくお願いします。

  • SQLで困っています。

    お世話になります。 SQLで困っています。 [環境] SQLServer2008 [テーブル] 売上テーブル 売上テーブルには日付、種別、金額のみ持っています。 [データ] 日付|種別|金額|残高 2014.01.01|繰越|1,000,000 2014.01.05|入金|35,980|1,035,980 2014.01.06|出金|290,000|745,980  ←最低額 2014.01.07|入金|955|746,935 2014.01.08|入金|33,020|779,955 2014.01.09|入金|34,960|814,915 2014.01.10|入金|41,960|856,875 上記データで最低額を求める簡潔なSQLを考えていますが、思いつきません。 どなたかご教授頂けたらと思います。

  • SQLで集計について分からないことがあります。

    SQLで集計について分からないことがあります。 まず、次のようなテーブルがあったとして 日付  店舗コード ブランドコード 金額 ---------------------------------------- 09-01 | 401101 | 01 | 10000 09-02 | 401101 | 01 | 20000 09-03 | 401101 | 01 | 30000 09-04 | 401101 | 01 | 40000 09-01 | 401101 | 02 | 10000 09-02 | 401101 | 02 | 20000 09-03 | 401101 | 02 | 30000 09-04 | 401101 | 02 | 40000 09-01 | 401101 | | 11111 09-02 | 401101 | | 22222 09-03 | 401101 | | 33333 09-04 | 401101 | | 44444 ブランドコードが'Null'の金額をブランドコードが'01'の金額に 日付をキーにして集計したいんですが、 可能でしょうか? なにか、良い方法があればお願いします。