Oracle9iのSQLPlusにて、日ごとのIDごとの小計をとりたいだけなのですが、
グループ関数の使い方がよくわかっていないのか上手くいきません。
以下のように出力したいと思い、以下のようなSQLを作成しましたが、、、、
<最終形>
入金日 ID 名前 請求開始日 請求終了日 合計金額
20080901 252 あああ 20080701 20080731 17000
20080901 252 空白 空白 空白 17000 ← ID=252の小計
20080901 534 いいい 20080601 20080630 18000
20080901 534 空白 空白 空白 18000 ← ID=534の小計
20080901 空白 空白 空白 空白 35000 ← 20080901の小計
<SQL文>
select 入金日,ID,名前,請求開始日,請求終了日,sum(入金額)
~
group by
rollup(入金日,ID,名前,請求開始日,請求終了日)
<現状>
入金日 ID 名前 請求開始日 請求終了日 合計金額
20080901 252 あああ 20080701 20080731 17000
20080901 252 あああ 20080701 空白 17000 ← 不要
20080901 252 あああ 空白 空白 17000 ← 不要
20080901 252 空白 空白 空白 17000
20080901 534 いいい 20080601 20080630 18000
20080901 534 いいい 20080601 空白 18000 ← 不要
20080901 534 いいい 空白 空白 18000 ← 不要
20080901 空白 空白 空白 空白 35000
上記、SQL文ではrollupにて全項目を指定しているから当然なのかもしれませんが、
試しに、小計対象外を外に出して「group by 名前,請求開始日,請求終了日,rollup(入金日,ID)」としてみたりしましたが上手くいきませんでした。
要はグルーピング対象外および小計対象外の項目の扱い方がよくわかっていないのかと思います。
どなたかご存知の方がいらっしゃれば是非ご教示いただけませんでしょうか?
宜しくお願いします。
No.5ベストアンサー
- 回答日時:
サブクエリとは、基本的にSELECTした結果をテーブルと見立てて使うことです(Viewのようなイメージです)。
したがって、サブクエリ自体は完結したものであって(*)、それを使うメインクエリはサブクエリを構成している個別のテーブルには関知しません。
つまり、メインクエリは以下のようなレイアウトのテーブルに対してSELECTを実行しているのと等しいです。
(項目名はサブクエリだけを抜き出して実行したときの戻りの項目名です)
TK14_NYUUKIN_DATE,
TK14_KANJYA_NO,
TK01_NAME,
TK13_SEIKYUU_START,
TK13_SEIKYUU_END,
SUMAMT
これらの値を生み出しているサブクエリ内のテーブルとは関係がなくなっています。それがBなどのエイリアスを指定できない理由です。
そう考えていただくと、テーブルの項目名にSUM(xxxx)などという名前は使えませんよね。それがSUMAMTという別名を付けている理由です。
(*) 別に相関サブクエリというものがあり、それはこの説明には当てはまらないかもしれませんが、これは必要になったときに勉強していただければと思います。
No.4
- 回答日時:
なるほど、このクエリならそうなるでしょうね。
「最初のSELECTの見出しを元にORDERを掛ける」というのは、「UNIONした場合は、SELECTの要素である項目に対してではなく、実行された結果に対してしかOrderが切れない」という意味だったのですが、今回のクエリは文字列結合してしまっているので、戻り列は1つですね。
したがって、ORDER BY 1,2はエラーになります。
そのため、今回のケースで、文字列結合する時点で項目別の並び順を指定できるようにするためには、サブクエリにする必要があると思います。
以下の通りです。
(OracleはOrderをかけるときにNULLの方が大きいとみなされるはずですから、これでいけると思います)
SELECT
TK14_NYUUKIN_DATE || ',' ||
TK14_KANJYA_NO || ',' ||
TK01_NAME || ',' ||
TK13_SEIKYUU_START || ',' ||
TK13_SEIKYUU_END || ',' ||
SUMAMT
FROM
(SELECT
B.TK14_NYUUKIN_DATE,
B.TK14_KANJYA_NO,
C.TK01_NAME,
A.TK13_SEIKYUU_START,
A.TK13_SEIKYUU_END,
SUM(B.TK14_NYUUKIN_GAKU) SUMAMT
FROM TK13_SEIKYUUSYO A
INNER JOIN TK14_NYUUKIN B ON TK13_KANJYA_NO=TK14_KANJYA_NO AND TK13_SEIKYUU_DATE = TK14_SEIKYUU_DATE
INNER JOIN TK01_KANJYA C ON A.TK13_KANJYA_NO = C.TK01_KANJYA_NO
WHERE B.TK14_NYUUKIN_DATE >= &1 AND B.TK14_NYUUKIN_DATE <= &2 AND B.TK14_NYUUKIN_GAKU > 0
GROUP BY B.TK14_NYUUKIN_DATE,B.TK14_KANJYA_NO,C.TK01_NAME,A.TK13_SEIKYUU_START,A.TK13_SEIKYUU_END
UNION
SELECT
B.TK14_NYUUKIN_DATE,
B.TK14_KANJYA_NO,
NULL,NULL,NULL,
SUM(B.TK14_NYUUKIN_GAKU)
FROM TK13_SEIKYUUSYO A
INNER JOIN TK14_NYUUKIN B ON TK13_KANJYA_NO = TK14_KANJYA_NO AND TK13_SEIKYUU_DATE = TK14_SEIKYUU_DATE
INNER JOIN TK01_KANJYA C ON A.TK13_KANJYA_NO = C.TK01_KANJYA_NO
WHERE B.TK14_NYUUKIN_DATE >= &1 AND B.TK14_NYUUKIN_DATE <= &2 AND B.TK14_NYUUKIN_GAKU > 0
GROUP BY ROLLUP(B.TK14_NYUUKIN_DATE,B.TK14_KANJYA_NO)
)
ORDER BY TK14_NYUUKIN_DATE,TK14_KANJYA_NO
この回答への補足
いろいろと勉強になります。。
まず、メインクエリにて、TK14_NYUUKIN_DATE等の項目に「B.」とテーブル名を付けると、ORA-0904が発生しますね。。このテーブルの別名はサブクエリだけに有効となるのでしょうか?そもそも別名は不要ですか?
また、メインクエリのSUMAMTとは単なる別名でしょうか?でもメインクエリに SUM(TK14_NYUUKIN_GAKU)と書いてもやはりORA-0904が発生します。
これはなぜなんでしょうか??
奥深いですね。。。
No.3
- 回答日時:
ORA-01785は戻りの列数が1つしかないのにORDER BY 2と切った場合などに出るエラーですが、当方では再現しません(11gですが)。
エラーの出るクエリを示していただけませんか。
この回答への補足
お手数おかけし申し訳ありません。
以下クエリです。
select
B.TK14_NYUUKIN_DATE || ',' ||
B.TK14_KANJYA_NO || ',' ||
C.TK01_NAME || ',' ||
A.TK13_SEIKYUU_START || ',' ||
A.TK13_SEIKYUU_END || ',' ||
SUM(B.TK14_NYUUKIN_GAKU)
from
TK13_SEIKYUUSYO A
inner join
TK14_NYUUKIN B
on
TK13_KANJYA_NO = TK14_KANJYA_NO
and TK13_SEIKYUU_DATE = TK14_SEIKYUU_DATE
inner join
TK01_KANJYA C
on
A.TK13_KANJYA_NO = C.TK01_KANJYA_NO
where
B.TK14_NYUUKIN_DATE >= &1
and B.TK14_NYUUKIN_DATE <= &2
and B.TK14_NYUUKIN_GAKU > 0
group by
B.TK14_NYUUKIN_DATE,
B.TK14_KANJYA_NO,
C.TK01_NAME,
A.TK13_SEIKYUU_START,
A.TK13_SEIKYUU_END
union
select
B.TK14_NYUUKIN_DATE || ',' ||
B.TK14_KANJYA_NO || ',' ||
null || ',' ||
null || ',' ||
null || ',' ||
SUM(B.TK14_NYUUKIN_GAKU)
from
TK13_SEIKYUUSYO A
inner join
TK14_NYUUKIN B
on
TK13_KANJYA_NO = TK14_KANJYA_NO
and TK13_SEIKYUU_DATE = TK14_SEIKYUU_DATE
inner join
TK01_KANJYA C
on
A.TK13_KANJYA_NO = C.TK01_KANJYA_NO
where
B.TK14_NYUUKIN_DATE >= &1
and B.TK14_NYUUKIN_DATE <= &2
and B.TK14_NYUUKIN_GAKU > 0
group by
rollup(B.TK14_NYUUKIN_DATE,
B.TK14_KANJYA_NO)
order by
1,2;
先ほどのエラーが発生します。
ちなみにorder byを外すと、小計が先頭に出力されてしまいます。
宜しくお願いします。
No.2
- 回答日時:
unionの場合は、unionで結合した最初のSELECTの見出しを元にORDERを掛けることになります。
したがって、最初のSELECTに使われている見出しが入金日、IDではなくなっているのではないでしょうか?
もしくは、私が書いたように「ORDER BY 1,2」と戻り値の列番号を指定する方法もあります。
この回答への補足
いずれのSELECTも見出しは同一です。
また、「ORDER BY 1,2」の場合、「ORA-01785:ORDER BY 項目は、SELECTリスト式の数値である必要あります。」エラーが発生してしまいます。
尚、「ORDER BY 1」は上手くいきますが・・・???
どうなってるのでしょうか?
No.1
- 回答日時:
ROLLUPはGROUP BYの対象に対して機械的に小計を算出してしまうものですので、目的の結果はシンプルには得られないと思います。
したがって、以下のいずれかの方法になるかと
・不要な小計を拾わない
SELECT 入金日,ID,名前,請求開始日,請求終了日,SUM(金額)
FROM テーブル
GROUP BY ROLLUP(入金日,ID,名前,請求開始日,請求終了日)
HAVING
(CASE WHEN 名前 IS NULL THEN 1 ELSE 0 END)
+(CASE WHEN 請求開始日 IS NULL THEN 1 ELSE 0 END)
+(CASE WHEN 請求終了日 IS NULL THEN 1 ELSE 0 END) NOT IN (1,2)
・小計は別につける
SELECT 入金日,ID,名前,請求開始日,請求終了日,SUM(金額)
FROM テーブル
GROUP BY 入金日,ID,名前,請求開始日,請求終了日
UNION
SELECT 入金日,ID,NULL,NULL,NULL,SUM(金額)
FROM テーブル
GROUP BY ROLLUP(入金日,ID)
ORDER BY 1,2
この回答への補足
amshid6さんいつもありがとうございます!
パーフェクトなご回答ありがとうございます。
union使えないかなぁ~と思っていましたので早速試してみました。
・・が、union後のselectにて、order by 入金日,IDでなぜかエラー(ORA-0904:無効な識別子です)が出てしまいます。
試しにunion後のselectのみを実行すればエラーは出ません。
unionにはなにか特殊な制限でもあるのでしょうか??
ご存知でしたら教えていただけないでしょうか?
宜しくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・【大喜利】【投稿~11/12】 急に朝起こしてきた母親に言われた一言とは?
- ・好きな和訳タイトルを教えてください
- ・うちのカレーにはこれが入ってる!って食材ありますか?
- ・好きな「お肉」は?
- ・あなたは何にトキメキますか?
- ・おすすめのモーニング・朝食メニューを教えて!
- ・「覚え間違い」を教えてください!
- ・とっておきの手土産を教えて
- ・「平成」を感じるもの
- ・秘密基地、どこに作った?
- ・【お題】NEW演歌
- ・カンパ〜イ!←最初の1杯目、なに頼む?
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
お土産というよりお使いなので...
-
公的機関への日付なし請求書
-
違法なアダルトサイトを閲覧し...
-
助けてください! 友だちと興味...
-
お世話になった人と縁を切りた...
-
月極駐車場を借りるのですが、...
-
生活保護者が車運転し、追突さ...
-
保育園で友達から顔に痕が残る...
-
近所の子に壊された 親に言いに...
-
トリニティーアカデミー (3ON...
-
同窓会費の突然の請求について
-
ホントに困ってます。 先日ワン...
-
解約
-
家具搬入の際、柱にキズをつけ...
-
サイトの後払い料金請求
-
大至急回答お願いします。 エポ...
-
見積書を出すとの事だったのに...
-
不当請求業者に住所を知られて...
-
支給お願いします。 抜ける無料...
-
公式有料アダルトコンテンツの...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
公的機関への日付なし請求書
-
お土産というよりお使いなので...
-
ラインギフトの支払い方法 につ...
-
倒産した会社のその後
-
1年半経ってからの結婚式費用の...
-
2年前の料金請求
-
別れた彼にお金を返して欲しい
-
請求書つきメールの書き方
-
ヤフーショッピングに出店して...
-
振替払込受付証明書をもらえな...
-
来月の頭にともだちとライブに...
-
SoftBank の延滞利息金の請求月...
-
ちょっと困ったフリーランスの...
-
【ETC-StationのETC0円キャ...
-
助けてください! 友だちと興味...
-
違法なアダルトサイトを閲覧し...
-
近所の子に壊された 親に言いに...
-
月極駐車場を借りるのですが、...
-
高1女子です。 詐欺メールに 住...
-
保育園で友達から顔に痕が残る...
おすすめ情報