あるサイトで・・・
”多くのRound関数は、偶数丸めを採用しており、
丸め単位のまんなかで、どっちつかずの場合は、偶数側を採用する。”
ということが書いてあるのを読みました。

しかし、SQL Server2000のクエリで
select round(1.25,1) と実行すると
1.2ではなく1.3 が返ってくるので、四捨五入されている気がします。

厳密な四捨五入と異なる値が返ってくるパターンはどういう式でしょうか?
それとも、SQL Server2000のRound関数は厳密な四捨五入なのでしょうか?

ご存知の方がいたら教えてください。
よろしくお願いします。

A 回答 (3件)

JIS丸めだと思います。


コンピュータに限らず、実験データなどの丸め方が決められていて、ROUND関数などはそれにしたがっている場合が多いです。

JIS Z8401-1999で検索すればいくつかヒットします。

参考URL:http://www.bsddiary.net/doc/jis-z8401.html
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
参考URLのページを見てみました。
数値の丸めって、いろいろあって難しいのですね。

お礼日時:2005/04/21 17:26

アメリカでは、四捨五入といったら偶数丸めだそうです。



私は、C#で開発を行っているのですが、C#では1.2と返ってきます。

1.24→1.2
1.25→1.2
1.26→1.3

1.25で1.3が返ってくるということは、SQLServer2000は厳密(日本風)な四捨五入なんでしょうね。

参考までに。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
言語によって違うのですね。
VBAで試してみたら、1.25→1.2でした。

お礼日時:2005/04/21 19:00

私も聞いた話なので、具体的な例は挙げられませんが、


十進数の0.1は2進数では、厳密には表示できないそうです。
ですから、2進数表記した場合、の中間値で偶数をとる
という意味ではないでしょうか。
    • good
    • 0
この回答へのお礼

回答ありがとうございます。
私も聞いた話では、具体的におかしくなる場合があるらしいのです・・・
いったいどういう数値だとおかしくなるのか知りたいところです。
プログラムでRoundを使用しているので、四捨五入でない値が戻ってくると困るってしまうのです。

お礼日時:2005/04/21 17:28

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

このQ&Aを見た人はこんなQ&Aも見ています

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

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

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

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;

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

QSQLserverのIF文について

どうしてもIF文がうまくいきません
IF文の中にIFを入れ子していますそのIFが複数の条件があります
今までACCESSではELSEIFで条件をいくらでも指定できたのですがSQLの場合はエラーになってしまいます
ご教授おねがいします
------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER FUNCTION [dbo].[scfc_part端数処理]
( @PTHASU nvarchar(10), @haken nvarchar(10) )
RETURNS
real
AS
BEGIN
DECLARE @PARTT real
DECLARE @PARTT_H real

if (not(@PTHASU is null))
if @haken='派遣' or @haken='臨時'
if substring(@PTHASU,4,2)>= 50
SET @PARTT = convert(int,LEFT(@PTHASU,2)+1)*60
--ここをいれるとエラー IF substring(@PTHASU,4,2)< 50 and substring(@PTHASU,4,2)>= 20
--ここをいれるとエラー SET @PARTT = convert(int,LEFT(@PTHASU,2)*60 +30
--ここをいれるとエラー if substring(@PTHASU,4,2)< 20
--ここをいれるとエラー SET @PARTT = convert(int,LEFT(@PTHASU,2)*60
ELSE
SET @PARTT = convert(real,LEFT(@PTHASU,2))*60 + convert(real,substring(@PTHASU,4,2))*1

ELSE
SET @PARTT= 0

SET @PARTT_H = convert(real,(floor(@PARTT/60*10000)/10000))

RETURN @PARTT_H

END

どうしてもIF文がうまくいきません
IF文の中にIFを入れ子していますそのIFが複数の条件があります
今までACCESSではELSEIFで条件をいくらでも指定できたのですがSQLの場合はエラーになってしまいます
ご教授おねがいします
------------------------------
set ANSI_NULLS ON
set QUOTED_IDENTIFIER ON
go
ALTER FUNCTION [dbo].[scfc_part端数処理]
( @PTHASU nvarchar(10), @haken nvarchar(10) )
RETURNS
real
AS
BEGIN
DECLARE @PARTT real
DECLARE @PARTT_H real

if (not(@PTHASU is...続きを読む

Aベストアンサー

マニュアルを読みましょう。

if 条件
真の時の命令文
else
偽の時の命令文

で、真または偽で命令文を2個以上書く場合は、begin~endでブロックを構成する必要があります。

参考URL:http://msdn2.microsoft.com/ja-jp/library/ms182717.aspx

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 型にはこのような概数の性質がある...続きを読む

QSQLで特定の項目の重複のみを排除した全項目を取得する方法

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のような構造になっている場合に「項目名1」について重複している項目を排除し、結果として


項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 B    え    イ    江

上のようなデータを取得したいのです。
この時に、Aの重複を排除して取得するレコードは1~3行目のどれでもよいです。
また、データを取得する際には必ずそのレコードの「全項目」を取得したいのでDistinctはうまく使えませんでした。

どなたか詳しい方、方法を教えてくださると幸いです。回答お待ちしております。

私は仕事上でデータベースを扱っていて、タイトルのような処理を行う必要があるのですが、いかんせん方法がわからずネット上を検索しても同様だったためここで質問させていただきます。

質問点を簡単に説明いたしますと、
たとえばAというテーブルがあって、

項目名1 項目名2 項目名3 項目名4
 A    あ    ア    亜
 A    い    ア    以
 A    う    ア    宇
 B    え    イ    江
 B    お    イ    尾

上のよ...続きを読む

Aベストアンサー

比較可能で一意性のある値をもてる項目6をテーブルに追加して、

select T.* from T, (select Item1,min(Item6) as Item6 from T group by item1) W where T.item6=W.item6;

――ってやるのが、一番手っ取り早いと思います。
他のところに影響がでないのであればですが。
oracleならrowidを使うとか、レコードの更新時刻を突っ込むとか。

Q日付の範囲検索がしたい

お世話になります。

テーブル名:info
フィールド名:no,date,name
フィールドのデータタイプ:int型,char型,char型

のデータベースがあります。dateにはyyyy/mm/ddの形でデータが入っているのですが、
そのdateから、例えば2004/01/01~2005/01/01までに該当するデータを検索して、抽出したいのですが、方法がわかりません。

SELECT REPLACE(date, '/', '') FROM info

で、“/”がないデータを取り出すことはできるのですが、その後どうしたら良いかがわかりません。
どなたかいい方法教えていただけないでしょうか?

Aベストアンサー

SELECT * FROM info WHERE date BETWEEN '2004/01/01' AND '2005/01/01'

で取れませんか?

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.区分

Q各伝票に対して明細を1行目だけ表示したい

たびたびお世話になります。

仮に以下のようなテーブルを考えるとします。

○テーブルA (伝票)
伝票番号 (PK)
顧客コード

○テーブルB (伝票明細)
伝票番号 (PK)
伝票明細 (PK)
注文コード
大盛り区分

レストランなどでお客さんが注文した注文伝票を
想像していただければ良いかと思います。
一つの伝票番号に対して、複数の伝票明細があると。
DB上は上記のように格納するとします。

ここでテーブル結合を使って、各伝票の1行目の明細を表示しながら
SQL1発で抜いてきたいと思います。どういうSQLを考えたら良いでしょうか?

テーブルBの表示項目が1つだけなら、

SELECT A.伝票番号, A.顧客コード, (SELECT TOP 1 注文コード FROM テーブルB B WHERE A.伝票番号 = B.伝票番号)
FROM テーブルA A

で良いのですが、複数項目となるとどうやったら良いのか判りません。

Aベストアンサー

 テーブルBの1行目レコードというのを、どう定義するかによって、答えが変わると思います。
 
例えば、テーブルBの伝票明細が1から順にふられる数字であって、その伝票明細=1のものだけ取ってくれば良いというのであれば、SQL文はいたってシンプルになるかと思います。
 
 SELECT A.伝票番号,A.顧客コード,B.伝票明細,B.注文コード,B.大盛り区分
FROM テーブルA AS A
INNER JOIN テーブルB AS B
ON A.伝票番号=B.伝票番号
AND B.伝票明細=1

こんな感じでしょうか。

 伝票明細が1から始まらず、「TOP 1」を使うというのであれば

 SELECT A.伝票番号,A.顧客コード,B.伝票明細,B.注文コード,B.大盛り区分
FROM テーブルA AS A
INNER JOIN テーブルB AS B
ON A.伝票番号=B.伝票番号
WHERE B.伝票明細=(SELECT TOP 1 C.伝票明細 FROM テーブルB AS C WHERE B.伝票番号=C.伝票番号)

こんな感じになります。この場合EXIST使ったりIN使ったり、細かい事を言えば色々方法はあるかと思います。でも基本的な考えは同じようなものです。

 

 テーブルBの1行目レコードというのを、どう定義するかによって、答えが変わると思います。
 
例えば、テーブルBの伝票明細が1から順にふられる数字であって、その伝票明細=1のものだけ取ってくれば良いというのであれば、SQL文はいたってシンプルになるかと思います。
 
 SELECT A.伝票番号,A.顧客コード,B.伝票明細,B.注文コード,B.大盛り区分
FROM テーブルA AS A
INNER JOIN テーブルB AS B
ON A.伝票番号=B.伝票番号
AND B.伝票明細=1

こんな感じでしょうか。

 伝票明細が1か...続きを読む

QSQL Serverにおける小数部の0表記について

お世話になっております

FLOAT型の数値を補正する為に、小数部10桁のdecimal型に変換すると
例えば 3.14 ならば 3.1400000000 と表示されてしまいます
RTRIMで0を消そうと思ったのですが、SQL Serverでは0のRTRIMは対応していないようです

FLOATやREAL型を使わずに、SQL Serverで小数部の0を消すには、どうしたら良いでしょうか?
ご教授頂ければ幸いです

Aベストアンサー

0をスペースに変更しRTRIMした後でスペースを0に戻すとか?
REPLACE(RTRIM(REPLACE(表示値,'0',' ')),' ','0')

Q日付型のフィールドに空白を入れる方法を教えてください

ASP(VBScript)でSQLサーバにINSET INTO文を使ってデータを格納しているのですが、日付の部分がNULLの時、「1900/1/1」が入ってしまいます。
そのまま、空白を入れる方法はどうやったらよろしいのでしょうか?

TABLE1の内容は
番号|内容|日付です。

INSERT INTO TABLE1 VALUES ( 1, 'あいう', '')

結果
1|あいう|1900/1/1

Aベストアンサー

あとは、プログラムの書き方次第ですね、、、


If hensu=Null Or hensu="" Then
dt = "NULL"
Else
dt = "'" & hensu & "'"
End IF

E_SQL = "INSERT INTO TABLE1 VALUES & _
"( 1,'あいう', " & dt& ")"
の様に書きます。

QSQLのVARCHARとVARCHAR2の違い

SQLについての質問です。
文字列型のVARCHARとVARCHAR2の違いについて教えてください。
まだ、初心者なのでなるべく分かりやすくお願いします。

Aベストアンサー

データベースによって、データ型の定義が違います。
私が知っている限りでは、
MS-SQLserverなどでは、可変長の文字列はvarcharですが、
Oracleでは、varchar2です。
他にも、MSのdatetimeに相当するものが、Oracleはdate型、という具合に名前が違います。
お使いのDBに沿ったデータ型の定義を調べると良いのではないでしょうか?
それぞれ違うと思いますよ。(似てると言えば似ているけど。)


人気Q&Aランキング

おすすめ情報