質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

88.34%

【SQL】CASE文について

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 3,936

programer

score 31

ORACLE SQLについてです。
SELECT文内で演算し、
取得したデータを取得されたデータによって分岐させたいです。

SELECT                      
  T1.aaa,                  
  T1.bbb,                 
  MAX(T1.ccc) - SUM(T2.fff) AS ENZAN,  
  FROM table1 T1, table2 T2
  WHERE T1.aaa = T2.aaa


このENZANを0未満なら0と表示し、0以上ならその演算した値で表示させたいです。
CASE文を使用して試してみましたが、様々なエラーが表示されてしまい、
うまく取得することができませんでした。

SELECT                      
  T1.aaa,                  
  T1.bbb,                 
  (CASE WHEN MAX(T1.ccc) - SUM(T2.fff) > 0 THEN MAX(T1.ccc) - SUM(T2.fff)
  WHEN MAX(T1.ccc) - SUM(T2.fff) <= 0 THEN 0
  END AS ENZAN),  
  FROM TABLE1 T1, TABLE2 T2
  WHERE T1.aaa = T2.aaa
 AND T1.bbb = T2.bbb

このような記述の仕方ではダメなのでしょうか。

T1
aaa VERCAHR2 P
bbb VERCAHR2 P
ccc NUMBER

T2
aaa VERCAHR2 P
bbb VERCAHR2 P
fff NUMBER

項目数は完全一致です。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 過去に投稿した質問と同じ内容の質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • m6u

    2016/09/06 19:31

    T1とT2のレコード数は完全一致でしょうか、それとも主従関係があったりするのでしょうか。

    キャンセル

  • programer

    2016/09/06 19:45

    テーブル構造を追記させていただきました。
    申し訳ありません。
    レコード数は完全一致です。

    キャンセル

  • m6u

    2016/09/06 19:51 編集

    どちらも、aaaとbbbが主キーになっているのか、そうじゃないのかも教えて下さい。ユニークキーなども。

    キャンセル

  • programer

    2016/09/06 20:04

    大変申し訳ありません。
    主キー等のテーブル情報も追記させていただきました。

    キャンセル

回答 2

checkベストアンサー

+1

SUM、MAX、MINなど集約関数を利用し、
かつ集約関数を用いていないカラム(今回の場合T1.aaaなど集約関数を使っていないもの)を指定したい場合は、*GROUP BY句でそのカラムを指定してあげるのがルールとなっています。
(※非集約項目はグループ化された際にどの値を表示しなければならないか分からないため)

そのため今回のクエリでは、
GROUP BY指定が必要となると思われます。

ただ提示していただいているテーブル構造的に、
今回の演算では全レコードのMAX、SUM値を取りたいのかなと思わるので、
期待した値を得るには「T1.aaa」、「T1.bbb」をSELECT句から外すか、
こいつらも集約関数で取得するようすると演算結果は想定通りのものとなるのかなと思われます。
(※後者のMAXかMINで取得した「T1.aaa」「T1.bbb」は期待通りの値表示とならない可能性が高いです)

また提示コードのケース式

(CASE WHEN MAX(T1.ccc) - SUM(T2.fff) > 0 THEN MAX(T1.ccc) - SUM(T2.fff)
  WHEN MAX(T1.ccc) - SUM(T2.fff) <= 0 THEN 0
  END AS ENZAN)

上記は列別名を指定する箇所が恐らく構文エラーとなっていると思われます。
正しくは下記のように修正するとケース式での構文エラーは起こらなくなるのではないでしょうか?

(CASE WHEN MAX(T1.ccc) - SUM(T2.fff) > 0 THEN MAX(T1.ccc) - SUM(T2.fff)
  WHEN MAX(T1.ccc) - SUM(T2.fff) <= 0 THEN 0
  END)  AS ENZAN    /* 列別名の指定箇所はカッコの外で */

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/07 09:41

    サンプルまで作成していただき、丁寧なご指摘ありがとうございす。
    確かにGROUP BYは必要ですよね。
    非集約項目をGROUP BYすることで解決することができました。
    ありがとうございました。

    キャンセル

  • 2016/09/07 21:42

    > programerさん
    少し気になったので補足をば。

    提示して下さっているテーブル構造では「aaa」、「bbb」の複合主キーとなっていますが、
    上記2項目で一意となるのであれば、集約自体不要となるのではないでしょうか?

    提示通りであればGROUP BYと集約関数を外した普通のSELECTで要件を満たせそうな気がします。

    またT1とT2のレコード数と主キーが完全一致する場合は、
    業務的に大きな意味がなければ1つのテーブルとするのも一案です。

    1つとした場合は下記のようなイメージとなります。

    NEW_T
    aaa VERCAHR2 P
    bbb VERCAHR2 P
    ccc NUMBER
    fff NUMBER

    キャンセル

0

CASE式 <http://docs.oracle.com/cd/E57425_01/121/SQLRF/expressions004.htm#i1033392> ですよね。
それ以前に、MAXやSUMするなら、GROUP BY句が必要でしょうね。
データ構造やテーブル同士の依存関係がわからないため、
じゃぁどう書けばいいかという回答は現段階ではいたしかねます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2016/09/06 19:46

    申し訳ありません。
    簡単なテーブル構造を追記させていただきました。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 88.34%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る