SQLで複数テーブルからグループごとの合計を求める方法

このQ&Aのポイント
  • 2つのテーブルから、グループごとの合計を求めるSQL文の書き方を教えてください。
  • テーブル名:グループ表と売上表があります。グループごとの売上合計一覧を出したいです。
  • 現在のSQL文では一部のグループの合計が正しく計算されません。正しい書き方を教えてください。
回答を見る
  • ベストアンサー

SQL文 2つのテーブルから、グループごとの合計を求める

テーブル名:グループ表 ID   グループ名 ------------------------- 100   Aグループ 101   Bグループ 102   Cグループ 103   Dグループ 104   Eグループ テーブル名:売上表 ID   売上年月日   売上額 ------------------------------ 101   20090401   1000 101   20090501   2000 102   20090401   2500 102   20090503   1500 103   20090404   3000 103   20090506   4000 上記の2つのテーブルがあります。 グループごとの売上合計一覧を出します。 ■求めたいSELECT文結果 グループ名   合計(売上額) ---------------------- Aグループ    0 Bグループ   3000 Cグループ   4000 Dグループ   7000 Eグループ    0 select グループ名,sum(売上額)  from (select グループ名,売上額     from グループ表,売上表      where グループ表.ID = 売上表.ID)   group by グループ名 では、 グループ名   合計(売上額) ---------------------- Bグループ   3000 Cグループ   4000 Dグループ   7000 となってしまい、うまくいきません・・・ どうように書いたらよろしいでしょうか?

  • Oracle
  • 回答数4
  • ありがとう数1

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

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

> 『ORA-25154: USING句の列の部分には修飾子を持てません』 先に例示したSQLのUSING句には、修飾子は無いのですが・・・。 「 USING(ID) 」の部分を 「 USING(グループ表.ID) 」などと変更しては無いでしょうか? USING句と同じことを ON を使っても書けますので、そうした場合はどうでしょうか? 例) -------------------------------------------------------------- SELECT グループ名, SUM(CASE WHEN 売上額 IS NULL THEN 0 ELSE 売上額 END) FROM グループ表 LEFT OUTER JOIN 売上表 ON(グループ表.ID = 売上表.ID) GROUP BY グループ表.ID, グループ表.グループ名 ------------------------------------------------------------------ ちなみにUSING句のカラムには表名修飾はできません。 http://okwave.jp/qa4871143.html

necktie88
質問者

お礼

実行できました!! ちなみにSUMは、 SUM(NVL(売上額,0))でもいけました。 SQLを始めてまだ3日、こういう教えていただける所があると、 大変助かります^^ありがとうござました

その他の回答 (3)

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

> でも、うまく実行できませんでした。。 エラーが出たのか望ましくない結果が表示されたのか、どちらでしょう? エラーの内容、もしくは、表示された結果はどうなりますでしょうか? また、昔のバージョンの Oracle ですとFROM句で結合条件の記述ができなかったりします。 Oracle のバージョンはいくつでしょう?

necktie88
質問者

補足

oracle 9iをです。 SI object browserを使っています。 以下のエラーがでました。よろしくお願いします。 『ORA-25154: USING句の列の部分には修飾子を持てません』

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

私も外部結合を使えば良いと思います。 また、サブクエリを使う必要も無いかと。 例) --------------------------------------------------------------- SELECT グループ名, SUM(CASE WHEN 売上額 IS NULL THEN 0 ELSE 売上額 END) FROM グループ表 LEFT OUTER JOIN 売上表 USING(ID) GROUP BY グループ表.ID, グループ表.グループ名 ------------------------------------------------------------------- なお、手元に実行環境が無いので確認はしていません。

necktie88
質問者

補足

ご回答ありがとうございます。 でも、うまく実行できませんでした。。

回答No.1

外部結合にすれば良いのでは? グループ名と売上額を right outer join で結合すれば良いのだと思います。 また、その際、AグループなどはNULLになりますので、売上額の箇所をNVL(売上額,0)として挙げる必要があると思います。 確認はしていませんが、 select グループ名,sum(売上額)  from (select グループ名,NVL(売上額,0)     from グループ表 RIGHT OUTER JOIN 売上表      ON(グループ表.ID = 売上表.ID))   group by グループ名 みたいな感じではどうでしょう?

necktie88
質問者

補足

ご回答ありがとうございます。 でも、うまく実行できませんでした。。

関連するQ&A

  • SQL文 合計値を出力する

    ID  項目CD  評価結果 ------------------------- A   1-1-1   ○ A   1-1-1   ○ B   1-1-1   × C   1-1-1   ○ A   1-2-1   ○ A   1-2-1   ○  B   1-2-1   ○ C   1-2-1   〇 上記のテーブルがあります 評価結果は、○と×があり、項目CDごとに集計を行い、項目CDが同じ場合は、○がいつくあっても1とみなして計算するということをおこないたいです 理想SELECT結果 ID  合計  -------------- A   2   (1-1-1で○が2つあるが、1つとして計算) B   1    C   2     SELECT ID,SUM(評価結果) FROM TABLE GROUP BY ID でIDと合計までは出せました 現在のSELECT結果 ID  合計  -------------- A   4   (すべての○の合計を出力) B   1    C   2   項目CDが同じ場合"○"を1つとして集計するにはどうすればいいのでしょか?

  • SQL文 合計と、特定の値を取り出す

    テーブル名:料金表 ID  項目CD  金額 ------------------------- 1   101   1000 1   102   2000  1   103    100 2   101   1000 2   102   2000 2   103    50 3   101   1000 3   102   2000 上記のテーブルがあります IDと、金額の合計と、項目CDが103のものだけ金額をだしたいのです 理想SELECT結果 ID  合計  項目CD:103 ------------------------- 1   3100   100 2   3050    50 3   3000    0(もしくはnull)  select ID,sum(金額) as 合計 from 料金表 where ID in(1,2,3) group by ID,金額 でIDと合計までは出せました 特定の項目の値を取り出すのはどうしたらいいでしょうか?

  • 要求を満たすことのできるSQL文を教えてください

    現在、売上の明細を明細IDごとにグループ化し合計値を表示させるプログラムを開発中です。 以下のような要件を満たすSQL文を教えてください。 【もともとの売上の明細のテーブル】 明細ID | NAME | KINGAKU 001  |商品A | 1000 001 |商品B | 500 001 |商品C | 300 002 |商品A | 1000 002 |商品D | 1500 【グループ化後のテーブル】 明細ID | NAME | KINGAKU 001 |商品A | 1800 002 |商品D | 2500 ・明細IDごとに金額を合計する。 ・NAMEの列については、その明細IDの中で最大の金額の商品名を入れる。 ※現在、明細IDごとに金額を合計するのはできているのですが、  もう1つの要件をどのようにすれば達成できるのか分からない  状況です。要件を満たすことのできるSQL文をぜひ教えてください。 よろしくお願いいたします。

  • SQL文でテーブルを作りたいのですが・・・

    テーブルを作りたいのですが、思い描くテーブルが作れず、困っています・・・ 例えばMさんがA→B→C→Dと旅行に行ったとします。 そのとき、行った場所によって日付が登録されるようにしたいと思っています。 このように、別な人もいろいろと旅行し、それぞれの日付があり、どんどんと格納していきます。 最初に ID id 日付 date 場所 point (名前はとりあえず、IDとします) でテーブルを作ろうとしましたが、これだとID一つにつき、日付と場所も一つずつしか入りませんよね? どういったテーブルを作ればいいでしょうか? 思い描くテーブルは下記のような感じです。 ID     日付      場所 -------------- 1  |2010/10/06 |  A   |2010/10/14 |  B   |2010/10/20 |  C   |2010/10/25 |  D -------------------------- 2  |2010/10/23 |  B    |2010/10/24 |  A    |2010/10/25 |  D    |2010/10/27 |  C -------------------------- 3  |2010/10/25 |  D    |2010/10/27 |  C    |2010/11/03 |  B    |2010/11/04 |  A    |2010/11/07 |  D    |2010/11/10 |  C ------------------------- 4  |2010/11/10 | B    |2010/11/15 |  A    |2010/11/16 |  D ・・・・・・・・・・・・・・・ このように一つのIDに対して、日付と場所がランダムの数で格納したいのですが、これって可能でしょうか? テーブルを2つ(以上)作り、外部キーを使ってもかまいません。 また、足りなければ違うIDなどでカバーしてもかまいません。 実際は、このようなテーブルを作り、一人毎の動線を調べるために活用したいと思っています。 Mさん:今日はAに行って、明日はBに行き、明後日はCに行った。すなわち動線は・・・のような感じです。 SQL文でテーブルを作ってください。 補足事項等ありましたらご指摘下さい。追加いたします。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • SQL GROUPで件数の一番多いレコードのみ取る

    SQL GROUPで件数の一番多いレコードのみ取る ORACLE10です。 次のようなテーブルがあります。 USER -----------テーブル名 ID,NAME,DATA----列名 1,A,any 1,A,any 1,B,any 2,C,any 3,D,any このテーブルから、IDをGROUPにして、さらに、一番使用頻度の多いNAMEを取得したいのです。 表示したいのは、IDとNAMEです。 つまり、取得結果例は次のようになります。 取得結果例 ID,NAME----列名 1,A 2,C 3,D SQL文をどのように作れば可能でしょうか? ちなみに、IDやNAMEのマスタテーブルはありません。 自分では、「(select ID, NAME, count(*) from USER group by ID, NAME) COUNT」で、COUNTを内部テーブルにして、グループ内で一番多いcount(*)をmaxで取得してみようかと思ったんですが、そこからアイデアが出ませんでした。

  • sql文

    現在試合結果のSQL文を作っています。 テーブルは下記内容になっており、今までは個々のテーブルに試合日程IDを渡して表示させていました。 今までは ("select from 試合日程テーブル") ("select from 試合結果テーブル where 試合日程ID = 試合日程id") ("select from 試合味方得点者テーブル where 試合日程ID = 試合日程id") ("select from 試合相手得点者テーブル where 試合日程ID = 試合日程id") 現在はもっと簡単にできるのではないかと思い作り直そうと思っています。 試合日程テーブル | id | 相手 | | 0001 | 相手A | | 0002 | 相手B | | 0003 | 相手C | 試合結果テーブル | id | 試合日程ID | 得点 | 失点 | | 1 | 0001 | 6 | 0 | | 2 | 0002 | 4 | 4 | | 3 | 0003 | 0 | 5 | 味方得点者 | id | 試合日程ID | 得点者 | | 1 | 0001 | Aさん | | 2 | 0001 | Aさん | | 3 | 0001 | Bさん | | 4 | 0001 | Cさん | | 5 | 0001 | Dさん | | 6 | 0001 | Dさん | | 7 | 0002 | Aさん | | 8 | 0002 | Bさん | | 9 | 0002 | Cさん | | 10 | 0002 | Dさん | 相手得点者 | id | 試合日程ID | 得点者 | 1 | 0002 | 相手Aさん | | 2 | 0002 | 相手Bさん | | 3 | 0002 | 相手Cさん | | 4 | 0002 | 相手Cさん | | 5 | 0003 | 相手Aさん | | 6 | 0003 | 相手Aさん | | 7 | 0003 | 相手Aさん | | 8 | 0003 | 相手Cさん | | 9 | 0003 | 相手Cさん | ここで各試合結果を出したときに相手得点者、味方得点者をidごとに出す方法を教えていただけないでしょうか? 試してみたところ ("select from 試合日程テーブル") ("select from 試合結果テーブル) ( left join 試合味方得点者テーブル on 試合結果テーブル.試合日程ID = 試合味方得点者テーブル.試合日程id") ( left join 試合相手得点者テーブル on 試合結果テーブル.試合日程ID = 試合相手得点者テーブル.試合日程id") (where 試合結果テーブル.試合日程ID = 試合日程id) で試してみましたがうまくきませんでした。 上記のテーブルの内容で1試合に対し、得点者がちゃんと表示されるようにしたいです。 例:試合日程IDが0001の場合は味方得点者が6人分表示され、00002の場合は味方得点者が4人分と相手得点者が4人分表示されるように。 わかりにくい説明ではあると思いますが、宜しくお願いいたします。 足りない部分を指摘いただけると幸いです。

    • 締切済み
    • PHP
  • PL/SQL グループ化について

    こんにちは。 現在以下のようなソースが存在するのですが、以下beforeのgroup byに設定している「D」をグループ化の対象外にしなければなりません。 ただし、「D」はSELECT対象であり、かつデータが文字型であり、集計関数の使用対象外(使用した場合に意図した結果とならない)などといった事情があり、単純にgroup by句から外すという対応ではうまくいきません。 誠に恐縮ですが、お知恵をお貸しいただけませんでしょうか? 【before】 ----------------------------------------------------- INSERT INTO 出力テーブル ( A , B , C , D ) SELECT  MIN(テ1.A) AS 別名A,     MAX(テ1.B) AS 別名B,     MAX(テ1.C) AS 別名C,     テ1.D FROM   テーブル1 テ1 WHERE  EXISTS      ( SELECT 0      FROM テーブル2 テ2    JOIN        テーブル3 テ3    ON  テ2.A = テ3.A      WHERE テ1.C = テ2.C      HAVING SUM(DECODE(テ3.G,'Yes',0,1)+DECODE(テ3.H,'Yes',0,1)) = 0 ) GROUP BY テ1.A,     テ1.B,    テ1.C,    テ1.D ;    ←ここを外したいです -----------------------------------------------------

  • グループ化したテーブルと他のテーブルの結合について

    お世話になります。PHP+MySQLでシステムを作っています。 商品のカテゴリーのテーブル・・・hametome_category(主キー:category_id ) 商品のテーブル・・・hametome_item(主キー:item_id ) 注文のテーブル・・・hametome_order(主キー:order_id ) 上記の3つのテーブルがあります。各テーブルにはそれぞれ、下記のようなデータを格納していて()内のカラムが含まれています。 hametome_category・・・カテゴリー名(category_id) hametome_item・・・商品名、単価など(category_id、item_id) hametome_order・・・注文内容等(category_id、item_id) この3つのテーブルを使い、カテゴリーごとの商品の一覧表を作り、一覧表の中に商品ごとの注文数量の累計を表示させたいと思っています。 【作りたい表のイメージ図】     単価 在庫数 注文数累計 商品A  100 1500 11000 商品B  120 1000 13000 商品C  130 1700 18000  ・  ・  ・ 表がずれていたらスイマセン^^; SELECT文を使ってデータを抽出するのですが、この際、 $sql="select * from hametome_category c,hametome_item i where i.category_id = $id and c.category_id = i.category_id ORDER BY item_id"; このようにすると任意のカテゴリーに属する商品の一覧表を出力する事は出来るのですが($idは前ページからPOSTされてきます。)、これに注文内容のデータ抽出を組み合わせようとするとうまくいきません。 この表に注文内容(hametome_orderに登録されているデータ)をitem_idでグループ化し合計したものを表示させたいです。 $sql="select *,SUM(order_amount) AS goukei from hametome_order GROUP BY item_id"; とすれば、注文数の累計をitem_idで合計しグループ化する事は出来るのですが(『order_amount』はhametome_orderテーブルに登録されている注文数です。)、この内容を最初のSELECT文にうまく組み込む事が出来ません。 どのようにすれば思うような結果を得られるでしょうか?ご教授のほどよろしくお願い申し上げます。

    • ベストアンサー
    • MySQL
  • SQL文おしえてください

    例えば、以下のような 2 つのテーブルがあるとします。 営業所テーブル (会社名) (担当者名)           会社A 担当者A          会社A 担当者B          会社B 担当者C          会社C 担当者D 商品売上テーブル (担当者) (売上)           担当者A  10万           担当者C   5万           担当者D  10万 これを以下のように会社名Aの会社だけを条件に「担当者B」の売上レコードがない場合でも、ゼロ件としてレコードを取得したいんですがどのようにすればよいのでしょうか。   (会社名)(担当者) (売上)    会社A  担当者A  10万    会社A  担当者B   0万 よろしくお願いします。

  • SQL文詳しい方お願いします!

    VBであるツールを作成しております。 以下の2つのテーブルがあります。 そこで現在は、SELECT WRITE_D.ID           FROM CHECKS INNERJOIN WRITE_D ON HECKS.ID=WRITE_D.ID          WHERE 閲覧権限=0 をVBのデータグリッド上に表示すると同じIDの数分の行が出来てしまいます。 ■条件 VBのツールからAさんが書き込みを行うと(2)に新規ID(*1)で1行追加され (1)にはユーザー数分*1が作成されます。 そこで書き込みの確認を行うと(1)のテーブルから該当ユーザーのID行が削除されます。 その際に、未確認のテーブルのみをSELECTで取得を行いたいのですが 何か良い方法はありますでしょうか?ご教示下さい。 (1)CHECKSテーブル ID   LNAME 31   Aさん 32   Aさん 31   Bさん 32   Bさん 31   Cさん 32   Cさん       ・       ・       ・ (2)WRITE_Dテーブル ID   内容     閲覧権限 31   ×××      0 32   ▲▲▲    1        ・        ・        ・