自分のお店を開く時の心構えとは? >>

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に入れて計算させると、ちゃんと正しい結果が出ます。

何が原因なのでしょうか?

このQ&Aに関連する最新のQ&A

A 回答 (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
118.97101449275362318
227.14516129032258064
344.62500000000000000
421.65625000000000000
5153.00000000000000000
633.00000000000000000
763.00000000000000001
    • good
    • 0
この回答へのお礼

す、すごい…(+_+)

たしかに、変数の型というのは盲点でした。

型が違うことで計算結果が変わるというのは困りますね。
そういう場合はエラーが出るものだと勝手に思い込んでました。

ご回答ありがとうございました。

お礼日時:2012/05/25 22:45

このQ&Aに関連する人気のQ&A

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!

関連するカテゴリからQ&Aを探す

このQ&Aを見た人が検索しているワード

このQ&Aと関連する良く見られている質問

QFloat型の時の計算結果がおかしい

ユーザー側で、Microsoft SQL Server2000を使用しています。
計算結果がおかしいので、仕事場で、SQL2008環境で互換モードでも、以下の現象が出てこまって
おります。テストで、確認しました。

23.0 - 22.1
の計算結果を0.9と出したいのですが、
 0.899999999999999
と結果が返ってきます。
どこが間違っているのでしょうか?

SELECT
[Field01] AS 'Field01'
,[Field02] AS 'Field02'
,[Field01]-[Field02] AS 'Field01-02'
,(CAST(23 AS FLOAT) - cast(22.1 AS FLOAT) ) AS 'test1'
,(CAST(23 AS REAL ) - cast(22.1 AS REAL ) ) AS 'test2'
FROM
[dbo].[Table01]

Aベストアンサー

間違ってはいません。

しかし浮動小数点データは概数であるため、データ型の範囲に含まれるすべての値を正確に表せるわけではありません。

SQLServer 2008 などの概数型は IEEE754 仕様に従っています。

概数型では、多くの場合、指定されたとおり正確な値が格納されません。正確な値にきわめて近い概数が格納されます。多くのアプリケーションでは指定した値と格納される概数のわずかな差は問題にはなりません。ただし、その差が問題になる場合もあります。float 型と real 型にはこのような概数の性質があるので、財務アプリケーション、丸めが行われる演算、等価性のチェックなど、正確な数値動作が必要な場合には、これらのデータ型を使用しないでください。

代わりに、int 型、decimal 型、money 型、smallmoney 型を使用することをお勧めします。


実際にはどういうことなのか、多少極端ですが、例を上げてみましょう。

いま、ここで新しいCPUを構想していて、4ビットで 0.00~4.00 までの実数を表現するものを考えているとします。

この例題で、4 ビットのうちの上位2ビットを 1の位、下位2ビットを小数点以下の位にすると仮定した場合、小数点以下は2ビットしかありませんから、2進数の 00 を 0.00、2進数の 01 を 0.025、2進数の 10 を 0.05、2進数の 11 を 0.075 と表現する合計4つのみとなります。そして、1の位は 0、1、2、3 です。
この範囲で表現できる数値では正確な4は表現できませんが、概数として表せば、3.75 が一番4に近い数値となるわけです。

実際にはもう少しビット数が多いわけですが、おおむねこのような仕組みで実数が表現されています。

間違ってはいません。

しかし浮動小数点データは概数であるため、データ型の範囲に含まれるすべての値を正確に表せるわけではありません。

SQLServer 2008 などの概数型は IEEE754 仕様に従っています。

概数型では、多くの場合、指定されたとおり正確な値が格納されません。正確な値にきわめて近い概数が格納されます。多くのアプリケーションでは指定した値と格納される概数のわずかな差は問題にはなりません。ただし、その差が問題になる場合もあります。float 型と real 型にはこのような概数の性質がある...続きを読む

Q他のデータベースとのテーブル結合

いつもお世話になっております。
VB.netでwindowsアプリケーションの作成しているところです。
SQLサーバーのテーブルを参照していますが、テーブルの結合は同じデータベース内にないと結合できないのでしょうか?

'SQL接続処理
Dim strConn As String = "Password='';User ID=sa;Initial Catalog=test;Data Source=server1"

と、testというデータベースがありその中に幾つかテーブルがあります。
このtestデータベースにないテーブルが必要になり、aaaデータベース内の
テーブルを結合しようとしたのですが、出来ません。
Catalog=test,aaaとやってみたり、SELECT * FROM tbl1,aaa.tbl2などとしてみましたが、遠いようです。
SQLのクエリを使って、テーブルの追加をすると同じデータベース内のテーブルしか出てこないので、出来ないのかなと思っていますがどうでしょうか?

わかる方がいましたら教えてください。

いつもお世話になっております。
VB.netでwindowsアプリケーションの作成しているところです。
SQLサーバーのテーブルを参照していますが、テーブルの結合は同じデータベース内にないと結合できないのでしょうか?

'SQL接続処理
Dim strConn As String = "Password='';User ID=sa;Initial Catalog=test;Data Source=server1"

と、testというデータベースがありその中に幾つかテーブルがあります。
このtestデータベースにないテーブルが必要になり、aaaデータベース内の
テーブルを結合しよう...続きを読む

Aベストアンサー

select * from tbl1,[aaa].[dbo].[tbl2]
のように、[データベース名].[オーナー].[テーブル名]の様式で指定すれば、良いかと思います。
(当然、権限の問題がない前提ですが・・)

QMAX値を条件にデータを取得するには?

SQL文で困っています。
ご教授下さい。


下記のようなデータがあった場合、それぞれの区分毎に
年月が最大(最新)のデータを取得したいです。
(実際には1レコードにその他項目があり、それらも取得します。)
<検索対象データ>
区分 年月   金額
-----------------------------
A   200412  600
A   200503  560
B   200311  600
B   200508  1000
B   200504  560
C   200508  400
C   200301  1100


<取得したいデータ>

区分 年月   金額
-----------------------------
A   200503  560
B   200508  1000
C   200508  400

よろしくお願いします。

Aベストアンサー

テーブル名をXXXとすると次のようなSQLでよいと思います。(最善の方法かどうかは自信がないですが)

select B.* from (select 区分, max(年月) as 年月 from XXX group by 区分) As A
inner join XXX as B on A.区分 = B.区分 and A.年月 = B.年月
order by B.区分

QOracle(オラクル)で、日付時刻型の検索方法について

質問させていただきます。
データベースはオラクルを使っていて、
SQL文で、抽出するときにエラーが出て困っています。

日付時刻型が「2005/05/26 19:13:00」という感じで入ってます。
2005/05/26 を抽出したいのですが、
BETWEEN '2005/05/26 00:00:00' AND '2005/05/26 23:59:59'

だと、エラーでできません。
どなた様か、ご教授よろしくお願いしますm(_ _)m

Aベストアンサー

日付検索を行う場合は、以下のように書式を含める必要があります。

col BETWEEN TO_DATE('2005/05/26 00:00:00','YYYY/MM/DD HH24:MI:SS') AND TO_DATE('2005/05/26 23:59:59','YYYY/MM/DD HH24:MI:SS')

ただ、厳密には

col >= TO_DATE('2005/05/26', 'YYYY/MM/DD')
AND
col < TO_DATE('2005/05/27', 'YYYY/MM/DD')

と書くべきでしょうね。

QSQLServerでの切り上げ処理

SQLServerで、小数部の丸め処理で困っています。

切り捨て → round(150.7, 0, 1)
四捨五入 → round(150.7)

というところまではなんとかわかったのですが、切り上げ処理がうまくいきません。

ceiling(150.7)やfloor(150.7)などいろいろ試してみたのですが、どうしてもうまくいきません(T-T)

どなたかわかる方がいらっしゃいましたらアドバイスお願いします。

Aベストアンサー

s_husky です。

select ID, (round(round(数量 + (0.99) * sign(数量), 2),0,1)) from table1;

負の値については考慮していませんでした!
面目ありません!


人気Q&Aランキング

おすすめ情報