SQLでのフラグ判断とSUM

このQ&Aのポイント
  • SQLを使用して、項目内のフラグを判断してSUMする方法について教えてください。
  • 期待する結果が得られないため、考え方ややり方についてアドバイスをいただきたいです。
  • 提供されたSQLを使用して、ymd、no、idごとにフラグの状態によってSUMする項目を変更する方法を教えてください。
回答を見る
  • ベストアンサー

SQL。項目内のフラグを判断して、SUMしたい。

やりたいこととしては、ymdとnoとidで一つにデータをまとめ、 各レコードの持つフラグ(a,b)の状態次第(両方trueならば)で、 SUMする項目(num1,num2)を適切に変更したいです。 下記みたいな感じでやってみたものの、まとめ方が悪いらしく期待した答えが出せません。 (何だかんだいじってみても同様、そして、張り付けたSQLは多分エラー。) 考え方が悪いのか、やり方が悪いのか、どなたかご教示いただきたく、よろしくお願いします。 ---------------------------------------- 実行SQL select ymd,no,id, SUM(   case     when max(a) and max(b)       then         num1   else     num2   end ) abc from (   select     '20180423' ymd,1 no,1 id,true a,true b,100 num1,300 num2   union   select     '20180423' ymd,1 no,1 id,false a,true b,200 num1,400 num2   union   select     '20180424' ymd,1 no,1 id,false a,false b,300 num1,500 num2   union   select     '20180424' ymd,1 no,1 id,true a,true b,400 num1,600 num2   union   select     '20180424' ymd,1 no,2 id,false a,true b,500 num1,700 num2 )table_1 group by ymd,no,id ---------------------------------------- 期待している答え ymd,no,id,abc 20180423,1,1,500 20180424,1,1,900 20180424,1,2,700 ----------------------------------------

  • Oracle
  • 回答数3
  • ありがとう数3

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

  • ベストアンサー
  • aa_akiya
  • ベストアンサー率100% (21/21)
回答No.3

No.1の回答で言葉足らずでした。 手近な実行環境がSQLSERVERでboolean型に対応していなかったのでtrueとfalseを文字列に置き換えて実行していました。 わざわざ変換しなくても動きます。 Oracleの環境は無いのですが、MySQLで動作したのでOracleでも問題ないと思います。 ---------------------------------------- select ymd,no,id, SUM(   case     when a = true and b = true       then         num1   else     num2   end ) abc from (   select     '20180423' ymd,1 no,1 id,true a,true b,100 num1,300 num2   union   select     '20180423' ymd,1 no,1 id,false a,true b,200 num1,400 num2   union   select     '20180424' ymd,1 no,1 id,false a,false b,300 num1,500 num2   union   select     '20180424' ymd,1 no,1 id,true a,true b,400 num1,600 num2   union   select     '20180424' ymd,1 no,2 id,false a,true b,500 num1,700 num2 )table_1 group by ymd,no,id

kumasangao-
質問者

お礼

よかったよかったとなってしまい、すっかり見ておらず、反応がだいぶ遅くなりました。 確かに、流してみたら期待した結果が得られました。 単純にSUMの中でのCase文の動作の理解が足りないようですね。。。MAXでまとめられるか!?とかやってるあたり。 投稿当時を思い出しながら、もうちょっと確認してみようと思います。 本当に、ありがとうございました。

その他の回答 (2)

  • aa_akiya
  • ベストアンサー率100% (21/21)
回答No.2

trueとfalseを文字列として、少し改変しました。 試したところ期待通りの結果が出力されました。 ----------------------- select ymd,no,id, SUM(   case     when a = 'true' and b = 'true'       then         num1   else     num2   end ) abc from (   select     '20180423' ymd,1 no,1 id,'true' a,'true' b,100 num1,300 num2   union   select     '20180423' ymd,1 no,1 id,'false' a,'true' b,200 num1,400 num2   union   select     '20180424' ymd,1 no,1 id,'false' a,'false' b,300 num1,500 num2   union   select     '20180424' ymd,1 no,1 id,'true' a,'true' b,400 num1,600 num2   union   select     '20180424' ymd,1 no,2 id,'false' a,'true' b,500 num1,700 num2 )table_1 group by ymd,no,id

kumasangao-
質問者

お礼

select ymd,no,id, max(a) a,max(b) b, SUM(   case     when a='true' and b='true' then num1     else num2   end ) abc from ( select ymd,no,id ,case   when a = true then 'true'   when a = false then 'false'   else 'null' end a ,case   when b = true then 'true'   when b = false then 'false'   else 'null' end b ,num1,num2 from (   select     '20180423' ymd,1 no,1 id,true a,true b,100 num1,300 num2   union   select     '20180423' ymd,1 no,1 id,false a,true b,200 num1,400 num2   union   select     '20180424' ymd,1 no,1 id,false a,false b,300 num1,500 num2   union   select     '20180424' ymd,1 no,1 id,true a,false b,400 num1,600 num2   union   select     '20180424' ymd,1 no,2 id,false a,true b,500 num1,700 num2 )table_1 )table_2 group by ymd,no,id なるほど。 文字列にするとまとまるとは、今の頭じゃ理解に至れないですね。 元テーブルはboolean型で直接は変えられないので、ワンクッション入れて、とりあえず上記のようにしてみました。 期待した結果が取れたと思います。 もう少し付け加えるものもあるので、改変して試してみたいと思います。 助かりました。ありがとうございます。

  • okwavey2
  • ベストアンサー率15% (251/1593)
回答No.1

考え方が悪いでしょうね。 一応技術者ってことで。 SQLの話をするなら、まずはテーブルの構造を明示してからですね。

kumasangao-
質問者

お礼

情報が足りずに、申し訳ありませんでした。 アドバイスのほどありがとうございます。

関連するQ&A

  • SQLのsum関数

    こんにちは。 PostgresのSQLが思うように動いてくれません!! そのIDを持っている人がどのくらいの数を持っているのかを抽出したいのです。 テーブルは下記です。 ********************************************* ★Aテーブル ID  名前  数  場所  日付 0001 みかん 1  冷蔵庫 0901 0001 みかん 4  倉庫  0901 0001 みかん 1  冷蔵庫 0901 0002 いちご 1  部屋  0901 0002 いちご 2  部屋  0801 0003 きのこ 6  倉庫  0901 ★Bテーブル ID  名前 0001 みかん 0002 いちご 0003 きのこ 0004 あいす ********************************************* となっている場合、下記SQLを実行すると select a.ID ,b.名前 ,sum(a.数) as 数 from Aテーブル a,Bテーブル b where a.日付 >= '0901' and a.日付 <= '0901' and a.ID = b.ID group by a.ID ,b.名前, a.数 結果が 0001 みかん 2 0001 みかん 4 0002 いちご 1 0002 いちご 2 となり0001は合計6で出て欲しいのに別々に出てしまいます。 理想では 0001 みかん 6 0002 いちご 3 で出て欲しいです。 たとえばこの場合、場所によってなど出てしまうものでしょうか? これはなぜなのでしょうか? よろしくお願いします。

  • SQL 条件付きDELETE文について

    SQLを見よう見まねでいじることになりました。。 AテーブルからBテーブルの以下の条件が当てはまるデータを削除する SQLを作りたいと考えています。  (1)Bテーブルの『DAT_FLG』が1  (2)A.テーブル『KNR_NO』 と Bテーブル『KNR_NO』が同じ  (3)Aテーブル『STR_YMD』 と Bテーブル『STR_YMD』が同じ  (4)Aテーブル『END_YMD』 と Bテーブル『END_YMD』が同じ 以下のようなSQLを考えましたがエラーとなってしまいました。 DELETE FROM A JOIN B ON A.KNR_NO = B.KNR_NO and A.STR_YMD = B.STR_YMD and A.END_YMD = B.END_YMD B.DAT_FLG = '1' DBはoracleを使っています。 どなたか教えてください。

  • SQL文について困っています

    ID(NUMBER型)と NUM(NUMBER型)と nenngetu (date型)を持ったテーブルAAAから、 ID=1000 のなかで日時が一番古い処理NOをselectするSQL文を書きましたが上手く実行されません。 select NUM from AAA where nenngetu = (select min(nenngetu) from AAA) and ID=1000; ID=1000の条件をはぶき、 select NUM from AAA where nenngetu = (select min(nenngetu) from AAA); でしたら、実行できました。 oracleで実行しようとしています。 どなたか、書き方を教えてください。

  • SQLで部分的にGROUP BYしたいとき(その2

    こんばんわ。 先日こちら(http://okwave.jp/qa/q7666702.html) で質問させていただきましたが、まだ問題があったため、 再度質問させていただきます。 以下のような20カラムある「出納帳」テーブルがあって、 同一日付の金額を集約してしまいたいです。 出納帳 ID 日付   金額 伝票 ・・・(全20カラム) 1 2012/8/20 1000 A01 ・・・ 2 2012/8/20 2000 A02 ・・・ 3 2012/8/21 -1000 B01 ・・・ 4 2012/8/21 -2000 B02 ・・・ 5 2012/8/22 3000 A03 ・・・ 6 2012/8/23 4000 A04 ・・・ 7 2012/8/24 -3000 B03 ・・・ 8 2012/8/24 -4000 B04 ・・・ 9 2012/8/27 5000 A05 ・・・ ↓「日付」で金額集約 ID 日付   金額 伝票 ・・・(全20カラム) 1 2012/8/20 1000 A01 ・・・ 2 2012/8/20 2000 A02 ・・・  2012/8/21 -3000    ・・・(-1000と-2000を集約) 5 2012/8/22 3000 A03 ・・・ 6 2012/8/23 4000 A04 ・・・  2012/8/24 -7000    ・・・(-3000と-4000を集約) 9 2012/8/27 5000 A05 ・・・ と集約キー以外はNULLにしたいのですが、 またまた、 ( SELECT ID, 日付, 金額, 伝票, ・・・ FROM  出納帳 WHERE  金額>=0 UNION ALL SELECT NULL, 日付, SUM(金額), NULL, ・・・ FROM  出納帳 WHERE  金額<0 GROUP BY 日付 ) ORDER BY 日付 とUNIONをする方法しか思いつかなかったのですが、 UNIONせずに端的に表現できるSQLはありますでしょうか?

  • sqlでNOT INでテーブルの値を比較

    テーブル ID NUM TNNO A 001 TN01 A 002 PC01 A 003 TN01 B 001 TNPC01 B 002 TN01 C 001 TN01 C 002 TN01 上記のようなテーブルがあります。 SQLで「NOT IN句」でテーブルの値の比較をやっているのですが、 結果が得られません。 IDが同じグループで、TNNOが違う行を取得したいのですが、 0件が返ってきます。 以下の結果を期待していますが、 ID NUM TNNO A 001 TN01 A 002 PC01 A 003 TN01 :どちらでも B 002 TN01 B 001 TNPC01 0件となります。 実行したクエリは以下ですが、 select * from tbl A where (A.num,A.tnno) not in (select num,tnno from tbl B where A.id=B.id); どこがいけないのでしょうか。理由がわかりますでしょうか。 NOT IN句を使うことがいけないのでしょうか。 取得するにはどう書き換えればよいのでしょうか。 よろしくお願いします。

  • SQL文で困っています。

    ID(NUMBER型)と NUM(NUMBER型)と nenngetu (date型)を持ったテーブルAAAから、 ID=1000 のなかで日時が一番古い処理NOをselectするSQL文を書きましたが上手く実行されません。 select NUM from AAA where nenngetu = (select min(年月) from D_KR_SAP_IFRIREKIKANRI) and ID=1000; ID=1000の条件をはぶき、 select NUM from AAA where nenngetu = (select min(年月) from D_KR_SAP_IFRIREKIKANRI); でしたら、実行できました。 oracleで実行しようとしています。 どなたか、書き方を教えてください。

  • 簡単なSQLを書くには?

    あるテーブルに列が40~50個ほど存在しており、そのテーブルに置いて合計を求めたいと考えております。 通常の方法であれば、 SELECT SUM(a1), SUM(a2), SUM(a3),.... `table` WHERE b1="0" OREDER BY c1 と書くのですが、列が40個もSUM()を書き続けるのが面倒なので何か簡単に合計を求めるSQLをご存じありませんでしょうか?

    • ベストアンサー
    • MySQL
  • SQL2005 で 複数列でのユニークの仕方

    SQL Server2005 Expressを使っているのですが。 下記のような3列の項目からなるテーブルがあり、ABCはそれぞれ数字として。 No1,No2,No3 A, B, A, F, B, C, B, F, B, , C, E, F 数字をユニークし、結果を A,B,C,E,F としたいのですが。 列(No1)だけでのユニークでよいなら Select Distinct(No1) ・・・・・ と書けばよいのでしょうが。 現在は、各列でユニークし、配列にいれて重複は削除するやり方をしているのですが。 この例では3列ですが実際は5列以上あります。 SQLでスマートなやり方はないでしょうか?

  • SQL文(基礎内容)

    アドバイスお願いします。 Oracle-Ver-8。 基本中の基本の中身になると思いますが、教えてください。こういったことができるのかお願いします。 SQL文の内容ですが、 ↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓ ************************************************** SELECT A.商品コード, A.商品名, SUM(DECODE(B.月,1,1月売上,0)) AS 1月, SUM(DECODE(B.月,2,2月売上,0)) AS 2月, SUM(DECODE(B.月,3,3月売上,0)) AS 3月, : : FROM (状態が'ABC'のもの) A GROUP BY A.商品コード,A.商品名 ************************************************* ↑↑↑ このSQLに異なった状態のもの、'DEF'からも項目を追加したい場合、一つのSQLでどのように表現したらよいのでしょうか?可能でしょうか? 例、 ************************************************** SELECT A.商品コード, A.商品名, SUM(DECODE(B.月,13,13,13月売上,0)) AS 13月, SUM(DECODE(A.月,1,1月売上,0)) AS 1月, SUM(DECODE(A.月,2,2月売上,0)) AS 2月, SUM(DECODE(A.月,3,3月売上,0)) AS 3月, : : FROM (状態が'ABC'のもの) A, (状態が'DEF'のもの) B WHERE 結合条件????? GROUP BY A.商品コード,A.商品名 ************************************************* よろしくお願いします。

  • 一つのSQLにできませんか??

    表領域のサイズと使用量を抽出するSQLを作成しています。 上は自動拡張サイズと現サイズを抽出するSQL、下は現在の使用量を抽出するSQLです。この二つを一つのSQLで作成ってできないでしょうか?? (1)自動拡張と現サイズを算出 select sysdate syoribi, a.tablespace_name, to_char(sum(a.MAXBYTES)/1024/1024, '999,999,990') jidou, to_char(sum(a.BYTES)/1024/1024, '9,999,990.9') gensaize from dba_data_files a group by a.tablespace_name (2)使用量を算出 select sysdate syoribi, b.tablespace_name, to_char(sum(b.BYTES)/1024/1024, '9,999,990.9') siyoryo from dba_segments b group by b.tablespace_name どうかよろしくお願いします。