• ベストアンサー

SQLでの計算結果がおかしい

SQLで調和平均(もどき)を計算したいのですが、下のようなSQL文で計算した結果が正しく出ないのです。 select ID, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from TABLE (各項に1を足しているのは、ゼロ除算を避けるための苦肉の策です) たとえば、A1=20, B1=10, C1=50 の場合、上記の結果が27.14と出ます。 (正しい計算結果は18.97のはずです) ちなみに、上とまったく同じ式をExcelに入れて計算させると、ちゃんと正しい結果が出ます。 何が原因なのでしょうか?

  • mtkame
  • お礼率70% (291/411)

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

  • ベストアンサー
回答No.1

A1, B1, C1の型は何ですか。 こちらで試した結果から,A1の型がINT型になっているのではないでしょうか。 ---- TEST ---- DECLARE @table1 TABLE ( A1 DECIMAL, B1 DECIMAL, C1 DECIMAL ) DECLARE @table2 TABLE ( A1 INT, B1 DECIMAL, C1 DECIMAL ) DECLARE @table3 TABLE ( A1 DECIMAL, B1 INT, C1 DECIMAL ) DECLARE @table4 TABLE ( A1 DECIMAL, B1 DECIMAL, C1 INT ) DECLARE @table5 TABLE ( A1 INT, B1 INT, C1 DECIMAL ) DECLARE @table6 TABLE ( A1 INT, B1 DECIMAL, C1 INT ) DECLARE @table7 TABLE ( A1 DECIMAL, B1 INT, C1 INT ) INSERT @table1 VALUES ( 20, 10, 50 ) INSERT @table2 VALUES ( 20, 10, 50 ) INSERT @table3 VALUES ( 20, 10, 50 ) INSERT @table4 VALUES ( 20, 10, 50 ) INSERT @table5 VALUES ( 20, 10, 50 ) INSERT @table6 VALUES ( 20, 10, 50 ) INSERT @table7 VALUES ( 20, 10, 50 ) select 1, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from @table1 UNION ALL select 2, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from @table2 UNION ALL select 3, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from @table3 UNION ALL select 4, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from @table4 UNION ALL select 5, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from @table5 UNION ALL select 6, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from @table6 UNION ALL select 7, 3 / ((1 / (A1 + 1) + 1 / (B1 + 1)) + 1 / (C1 + 1)) as HARMEAN from @table7 (列名なし) HARMEAN 1 18.97101449275362318 2 27.14516129032258064 3 44.62500000000000000 4 21.65625000000000000 5 153.00000000000000000 6 33.00000000000000000 7 63.00000000000000001

mtkame
質問者

お礼

す、すごい…(+_+) たしかに、変数の型というのは盲点でした。 型が違うことで計算結果が変わるというのは困りますね。 そういう場合はエラーが出るものだと勝手に思い込んでました。 ご回答ありがとうございました。

関連するQ&A

  • 計算結果をCASE WHENで判断したとき、ELSEで計算結果をそのまま持ってくるSQL文法は?

    SQL SERVER2005を使用しています。 テーブルAがあり、Aが持つフィールド「suuchi」には数値が入っているとします。 suuchiフィールドの値を計算して、その結果が0以上なら計算結果を。負の数なら0を出力するSQL文を書きたいのです。 CASE WHEN を使用して以下のSQLを書きました。 SELECT CASE WHEN ( suuchi*2 + 1 ) < 0 THEN 0 END FROM テーブルA; しかし、結果は計算結果が負の数の場合は「0」になりますが、0以上の場合が表示されませんでした。 理由は、CASE WHEN でELSEを省略した場合、結果がNULLになるためと思われます。 以下のSQLでは期待とおりの結果が得られます。 SELECT CASE WHEN ( suuchi*2 + 1 ) < 0 THEN 0 ELSE ( suuchi*2 + 1 ) END FROM テーブル; しかし、同じ計算式を2回書くのは今一正しくないように思えます。 CASE WHEN で計算結果を判断した場合、ELSEでは計算済みの結果を取ることはできないのでしょうか? 上は例として書いたので簡単な計算式ですが、実際私が業務で使用している計算式はかなり長いため できれば式を2回書くことを避けたいのです(SQL文が長くなるため)。 計算結果に一時的に別名をつけようとして、以下のようなSQL文を書いたのですが「AS 付近にエラーがあります」といわれます。 SELECT CASE WHEN ( suuchi*2 + 1 ) AS TMPFIELD < 0 THEN 0 ELSE TMPFIELD END FROM テーブル; 質問は2点です。 1) 計算式の結果をCASE WHEN で判断した場合、ELSEの時は計算結果を取得したい場合は、再度同じ計算式を書く必要がありますか? 2) 上の答えが「必要ない」場合、上記条件を満たすSQLの書き方をご教示いただけませんでしょうか? なお、質問文の文章、SQLServerの環境の記述不足、SQL文等で意味不明な箇所がありましたらご指摘ください。 以上です。よろしくお願いします。

  • SQLの結果に納得できません。どなたか解説していただけないでしょうか。

    あるSQLの実行結果がどうも納得できないのです。 こちらで詳しい方に解説していただけたらと思い投稿しました。 以下SQL1の実行結果ですが、なぜ'A'の後ろに半角スペースが入ってしまうのでしょうか? とりあえず私はSQL2のように書き直して本番のSQLは対応しました。 しかし、なんともスッキリできないのです・・・。 (前提条件) customerテーブルは10件あるとします。 (SQL1) select 'A'|| (select to_char(count(*),'000') from customer) expr1 from dual; (SQL1結果) 'A'の後ろになぜか半角スペースが入ります。 expr1 ------- A 010 (SQL2) select 'A'|| trim((select to_char(count(*),'000') from customer)) expr1 from dual (SQL2結果) 'A'の後ろに半角スペースは入りません。 expr1 ------- A010 以上よろしくお願いします。

  • 1つのSQLにしたいです

    1つのSQLにしたいです 以下のSQLを1つにしたいです。 select a, b, c, '1' event_type from sample where type = '1' select a, b, c, '2' event_type from sample where type = '2' select a, b, c, '3' event_type from sample where type = '3' ポイントはselect分に結果によって'1'、'2'、'3'といれたいです。 初心者的質問で申し訳ありません。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • 意味は同じはずなのに結果が違います。

    SELECT * FROM テーブルA LEFT OUTER JOIN ( SELECT * FROM テーブルB WHERE テーブルB.列X IS NOT NULL) as テーブルB ON テーブルA.列A = テーブルB.列A SELECT * FROM テーブルA LEFT OUTER JOIN テーブルB ON テーブルA.列A = テーブルB.列A WHERE テーブルB.列X IS NOT NULL 上のSQLも下の同じ事をしてると思うのですが 上では検索結果が10件出た場合 下では0件になってしまいます。 SQL自体シンプルで間違っていないと思うのですがなぜでしょうか?

  • sqlについて

    下に書いたsqlのコードの内容(どういう処理でどういう結果になるのか)が知りたいです。 どなたかわかる方教えてください。 select b.ym, b.no,     isnull(e.sumcnt,0)as val, null as bunsi, null as bunbo from (select distinct ym,no from Table_A)b inner join (select ym from Table_B where cd=1)d on b.ym=d.ym left outer join (select b1.ym,b1.no,sum(c1.cnt)as sumcnt from Table_A b1 inner join (select ym from Table_B where cd=1)d1 on b1.ym=d1.ym inner join Table_C c1 on b1.ym=c1.ym group by b1.ym,b1no)e on b.ym=e.ym and b.no=e.no

  • ACCESSのSQLの書き方

    ACCESSでのSQL文の書き方を教えてください。 テーブルtbl_Aとテーブルtbl_Bがあり, tbl_Aで得られた数値とtbl_Bで得られた数値を加えたものを結果として表示します。 どう書けばよろしいのでしょうか。どうしてもエラーになってしまいます。 イメージとしてはこんな感じです。 select (select ~~ from tbl_A where ~~)+(select ~~ from tbl_B where ~~) (もしoracleならば,「from dual」というのを最後に付けるんですが。)

  • access で結果の出るSQLが、MySQLではできなくて困っていま

    access で結果の出るSQLが、MySQLではできなくて困っています。 普段、ちょっと古いですが、Access2002を使用しています。 どうしても、Linuxサーバー上でデーターベースを利用する必要がでて、Fedora13に、mysql 5.1.48 をyamでインストールしました。 ところが、必要なSELECT検索が出来ず、困っています。 次のようなテーブル構造だと思ってください。 table A id|No ---- a1|01 b1|11 c0|20 table B No|option1|option2 ---------- 01|L   |Red 01|S   |Red 01|L   |Green 01|S   |Green 11|S   |(値なし) 11|L   |(値なし) このNoとオプション1、2から、IDを割り出したしたいのです。 オプション1,2は、存在していないデータもあります。 Accessなら、table A の No と table Bのoption1、option2 を &で結んで、結合プロパティをtable Aの全レコードに指定したSQL SELECT A.id, [A].[No] & [B].[option1] & [B].[option2] AS test FROM A LEFT JOIN B ON A.[No] = B.[No] WHERE ((([A].[No] & [B].[option1] & [B].[option2])="01LRED")); とすれば、a1 と結果が返ります。 table B にオプション値の登録のないものでも、 SELECT A.id, [A].[No] & [B].[option1] & [B].[option2] AS test FROM A LEFT JOIN B ON A.[No] = B.[No] WHERE ((([A].[No] & [B].[option1] & [B].[option2])="20")); とすれば、C0が返ってくれます。 ところが、同じテーブル構成をMySQLに作成し、 SELECT A.id, A.No & B.option1 & B.option2 AS test FROM A LEFT JOIN B ON A.No = B.No WHERE A.No & B.option1 & B.option2 = "01LRED"; を入力してみましたが、結果が出ません。 エラーらしきものといえば、 Empty set, 5 warnings (0.00 sec) が表示されています。 結合の方法が違うのかと思い、Googleで調べ SELECT concat(A.id, A.No & B.option1 & B.option2) AS test FROM A LEFT JOIN B ON A.No = B.No WHERE (A.No & B.option1 & B.option2) = "01LRED"; と、concat を使ってみましたが、だめでした。 MySQLで、上記のように複数のテーブル/フィールドを結合して、その値をもとに検索することはできないでしょうか? よろしくお願いいたします。

    • ベストアンサー
    • MySQL
  • SQLで・・

    すみません、教えてください。 次のようなデータがあります。 table_A Name1 Name2 ----------- 1   2 3   4 table_B ID    Name --------------- 1     あ 2     い 3     う 4     え 次のような検索結果が欲しいとします。 Name1 Name2 ------------- あ    い う    え この結果を導くSELECT文はどう書けばいいでしょうか? 今、 select B.Name as Name1, C.Name as Name2 from table_A A, table_B B, table_B C where A.Name1=B.ID AND A.Name2=C.ID とやってみましたが、検索結果は0件になってしまいます。 お知恵をお貸しください!

  • SQL: select  結果のカラム結合

    selectの結果(文字列)を結合ってできますか。 例えば以下のテーブルがあって、カラムAとBを結合した結果が欲しいのです。Aカラム-Bカラム という結果が欲しいのです。 (つなぎ文字はわかりやすければなんでも可) なんとかスマートに一つのSQLでできないでしょうか。 A | B | C ---+-----+--- 1 | aaa | testtest 2 | bbb | hogehoge SQL > select .... 期待する答え ans | C ---+-----+--- 1 -aaa | testtest 2-bbb | hogehoge

  • Access SQLでnull値のOrderby

    お世話になります、 AccessのSQLについて教えてください。 例えば打率をSQLの中で計算させたとします。その値で Order by して表示させたいのですが、計算結果がnull (打席が0の人)は分母が0になってしまい値が存在しない (null)ですよね、その場合にOrder byを行うとSQLでエラーになってしまいます。 このような場合皆様ならどのように回避されるでしょうか? select B.daritu From (select hit/dasu As daritu From A ) As B Order by B.daritu