• ベストアンサー

SUM関数の中にCASE WHEN文を入れ子にするような方法

PHP4+MySQL4.0で、MYTABLEに、運転距離と給油量があります。 運転手別の通算運転距離を通算給油量で割り算して、運転手ごとの燃費を出したいですが、 場合によって燃料が軽油だったりガソリンだったりで、単純にSUMできません。 そこで、ガソリンの場合は軽油換算(給油量×0.9)しようと思い。 SUMの中にCASE WHENを入れ子したのですが、エラーになります。 運転手 月 運転距離 給油量 燃料 UNTEN M KYORI  KYUYU  NENRYO ―――――――――――――――― Aくん  6  200    22   軽油 Bくん  5  300    34   軽油 Bくん  6  500    52   ガソリン Cくん  5  600    65   軽油 Cくん  6  100    11   ガソリン  : 最初は、↓を運転手ごとにPHPでループさせていたのですが、 ■SQL1 SELECT SUM(KYORI)/SUM(KYUYU) AS SUMNENPI FROM MYTABLE WHERE UNTEN = 'Aくん' 燃料が軽油なら1をかけ、ガソリンなら0.9をかけなければいけないので、↓を考えました。 (換算後の合計給油量をKYUYURYOと呼びます。ただし距離と給油量がゼロ以上の場合だけ) ■SQL2 CASE IFNULL(KYORI,0) * IFNULL(KYUYU,0) WHEN 0 THEN NULL ELSE KYUSU * (CASE NENRYO WHEN '軽油' THEN 1 WHEN 'ガソリン' THEN 0.9 ELSE 0 END) END AS KYUYURYO 上記のSQL2を、SUM(KYUYU) の()内に置き換えるとエラーになってしまうのです。

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

  • ベストアンサー
  • HTTP500
  • ベストアンサー率40% (2/5)
回答No.2

SUMにCASEで渡せばいいんじゃないですか? SUM ( CASE NENRYO WHEN '軽油' THEN 1 * KYUYU WHEN 'ガソリン' THEN 0.9 * KYUYU ELSE 0 END )

litton101
質問者

お礼

HTTP500さん、アドバイスありがとうございました。 >SUMにCASEで渡せばいいんじゃないですか? ご教示の方法で、無事解決しました。 わたしの例文ではだめで、同じようにみえるけど HTTP500さんの方法では問題なく動くのですね(^_^; おかげさまで、既存のソースを120%活用して 目的を達成できました。 本当にありがとうございました。

その他の回答 (1)

  • yambejp
  • ベストアンサー率51% (3827/7415)
回答No.1

PHPでループする必要はないでしょう? まずこうしてみてください。 SELECT *,`KYUYU`-(`NENRYO`='ガソリン')*0.1*`KYUYU` AS `CHOSEI_KYUYU` FROM `MYTABLE` ガソリンの場合だけ調整した給油値がでますね? これをつかってUNTENでグルーピングしてSUMをとれば いけるでしょう? SELECT `UNTEN`,SUM(`KYORI`)/SUM(`KYUYU`-(`NENRYO`='ガソリン')*0.1*`KYUYU`) AS `NENPI` FROM `MYTABLE` GROUP BY `UNTEN`

litton101
質問者

お礼

yamabejpさん、いつもご教示ありがとうございます。 PHPの方は、業者さんが作った大枠に 最小限のカスタマイズで今回のような目的を達成したい 次第で、できればループは残しておきたいと思っていました。 ご教示の内容ですが、つくづく自分の視野の狭さを痛感しました。 素晴らしい方法です。一生かかっても思いつかない方法です。 今回は#2さんの方法で解決しますが、将来的に使う場面が 出てきそうです、活用させていただきます。

関連するQ&A