SQL四舍五入到最接近的百分之一

SQL四舍五入到最接近的百分之一,sql,ms-access,Sql,Ms Access,我正试图安排一轮接近百分之一的投票。救命啊 我不希望答案是104.7648,我希望答案是104.76 我不希望答案是104.7668,我希望它是104.77。四舍五入(值,2)我认为您没有提供足够的数据来推断您需要什么 如果您的规范告诉您使用哪种舍入算法,请发布它 如果您的规范没有告诉您哪种舍入算法,那么就向设计师提出问题 一般来说,SQL不是为数学计算而设计的。考虑在另一层中进行舍入。如果需要,请确保使用十进制存储值,并在前端添加一个超出要求的小数位。请参阅: 引用一段摘录: “Round函数

我正试图安排一轮接近百分之一的投票。救命啊

我不希望答案是104.7648,我希望答案是104.76


我不希望答案是104.7668,我希望它是104.77。

四舍五入(值,2)
我认为您没有提供足够的数据来推断您需要什么

如果您的规范告诉您使用哪种舍入算法,请发布它

如果您的规范没有告诉您哪种舍入算法,那么就向设计师提出问题

一般来说,SQL不是为数学计算而设计的。考虑在另一层中进行舍入。如果需要,请确保使用
十进制
存储值,并在前端添加一个超出要求的小数位。

请参阅:

引用一段摘录:

“Round函数执行从圆到偶数的转换,这与从圆到大的转换不同。” --微软

格式总是四舍五入

UPDATE prodfeatures2 SET featureprice = ROUND(featureprice * 0.6316,2)
在这种情况下:

  Debug.Print Round(19.955, 2)
  'Answer: 19.95

  Debug.Print Format(19.955, "#.00")
  'Answer: 19.96

以下是我针对MS Access的回答:这个问题有些可疑

除非
featureprice
是一个非常大或非常小的数量,并且元数据表明它不是,否则乘以十进制文本(如
0.6316
)将把结果共享到type
decimal
。现在,本质上,
decimal
在Access中键入(ACE、Jet等),通过截断进行舍入,例如,如果您可以这样做:

选择CAST(104.7668作为十进制数(17,2)

它将转到
104.76
…当然,您不能在Access中执行此操作,因为它不支持SQL标准语法,并且它自己的专有语法
CDEC()
从第一天起就被破坏了,并且仍然没有在ACE中修复(rolls eyes)。但是您可以做的是:

UPDATE prodfeatures2 SET featureprice = CCUR(Format(featureprice * 0.6316,'#.00'))
我猜您的
prodfeatures2
列的类型是
CURRENCY
,我建议,如果您不希望将结果转换为
十进制
,并且我们可以从您的算法中看出您不希望,那么您的SQL就缺少转换

此外,您希望结果保留两位小数,但原始值不保留两位小数。例如:

CREATE TABLE TestDecimal 
(
 dec_col DECIMAL(17, 2) NOT NULL UNIQUE
);

INSERT INTO TestDecimal (dec_col) 
   VALUES (104.7668);

SELECT dec_col FROM TestDecimal;
-- 104.76 -- truncated
SELECT CCUR(CCUR(165.87) * 0.6316)
-- 104.7635 -- too low

SELECT CCUR(CCUR(165.88) * 0.6316)
-- 104.7698 -- too high

SELECT CCUR(CCUR(165.872) * 0.6316)
-- 104.7648 -- spot on
因此,之前的过程无法将值四舍五入到2 dp,但是在这个过程之后,需要将值四舍五入到2 dp?正如我所说的,这里可能会有一些气味,并且您还没有找到错误……或者,这比您在这里透露的更多



您断言通过十进制进行多倍运算会将结果强制为十进制数据类型的依据是什么

(开玩笑地说)为什么,我当然在ACE/Jet的用户手册中读到了。只是开玩笑,没有。就像JET4.0中的任何东西一样,你只是在做实验

十进制文字(例外情况下,例如非常大和非常小的值)的类型为
Decimal
。例如:

CREATE TABLE TestDecimal 
(
 dec_col DECIMAL(17, 2) NOT NULL UNIQUE
);

INSERT INTO TestDecimal (dec_col) 
   VALUES (104.7668);

SELECT dec_col FROM TestDecimal;
-- 104.76 -- truncated
SELECT CCUR(CCUR(165.87) * 0.6316)
-- 104.7635 -- too low

SELECT CCUR(CCUR(165.88) * 0.6316)
-- 104.7698 -- too high

SELECT CCUR(CCUR(165.872) * 0.6316)
-- 104.7648 -- spot on
返回“Decimal”

当使用包含
DECIMAL
类型值的数字运算符(加、减、乘、除)时,将强制结果为
DECIMAL
(与上述相同的例外情况适用)

一个简单但有效的测试是,为每种数字数据类型创建一个具有一列的表,为每种数据类型插入一个小值(例如1),然后用十进制文字(例如0.1)加/减/乘/除:

SQL DDL:

SELECT TYPENAME(0.1)
SQL DML:

CREATE TABLE TestNumericDataTypes
(
 TINYINT_col TINYINT NOT NULL, 
 SMALLINT_col SMALLINT NOT NULL, 
 INTEGER_col INTEGER NOT NULL, 
 REAL_col REAL NOT NULL, 
 FLOAT_col FLOAT NOT NULL, 
 DECIMAL_col DECIMAL NOT NULL, 
 CURRENCY_col CURRENCY NOT NULL, 
 YESNO_col YESNO NOT NULL, 
 DATETIME_col DATETIME  NOT NULL
);
INSERT INTO TestNumericDataTypes 
(
 TINYINT_col, SMALLINT_col, INTEGER_col, 
 REAL_col, FLOAT_col, DECIMAL_col, 
 CURRENCY_col, YESNO_col, DATETIME_col
) 
VALUES (1, 1, 1, 1, 1, 1, 1, 1, 1);
SQL DML:

CREATE TABLE TestNumericDataTypes
(
 TINYINT_col TINYINT NOT NULL, 
 SMALLINT_col SMALLINT NOT NULL, 
 INTEGER_col INTEGER NOT NULL, 
 REAL_col REAL NOT NULL, 
 FLOAT_col FLOAT NOT NULL, 
 DECIMAL_col DECIMAL NOT NULL, 
 CURRENCY_col CURRENCY NOT NULL, 
 YESNO_col YESNO NOT NULL, 
 DATETIME_col DATETIME  NOT NULL
);
INSERT INTO TestNumericDataTypes 
(
 TINYINT_col, SMALLINT_col, INTEGER_col, 
 REAL_col, FLOAT_col, DECIMAL_col, 
 CURRENCY_col, YESNO_col, DATETIME_col
) 
VALUES (1, 1, 1, 1, 1, 1, 1, 1, 1);
我不确定您是否可以通过Access界面创建所有这些类型,并且您可能不知道如何运行SQL DDL,因此这里有一些普通的VBA(不需要Access,例如可以从Excel运行,不需要引用,例如仅复制和粘贴):

每种情况下的结果都是十进制的


前面提到的一些例外情况:

等于其
整数
值的十进制文字,例如

选择TYPENAME(1.0)

返回“Long”(这是Jet 4.0的
INTEGER
类型的VBA等效项——为什么它显示VBA名称而不是我不知道的Jet名称)

…值超出
整数范围时除外:

选择类型名称(1000000000)

返回“十进制”

…当值超出
十进制范围时,请执行以下操作:

选择TYPENAME(1E29)

返回“Double”(相当于Jet的浮动的VBA)

在正范围内,使用
DECIMAL
literal对值进行操作将保留类型为
FLOAT
,例如

选择TYPENAME(1E29+0.1)

返回“Double
FLOAT`)

…而在负数范围内,它与
DECIMAL

选择TYPENAME(1E-29+0.1)

返回“Decimal”

交叉边界时,协同工作的方式不同,例如(注意,
整数的上界为2147483647):

选择TYPENAME(2147483648)

返回十进制数`

……鉴于:

选择TYPENAME(2147483647+1.0)

返回“Double”(
FLOAT


毫无疑问,我还没有发现其他例外情况。

选择四舍五入(将104.7668转换为十进制(6,2)),2)作为roundof;

请将其应用于此更新对账单,以便我可以看到将其放置在何处:update prodfeatures2 SET featureprice=featureprice*0.6316;请注意,舍入是用于统计目的,可能不适合财务舍入。很可能帐户需要舍入(104.745,2)等于104.75,而不是返回的104.74……也就是说,VBA Round()使用“银行家舍入法”虽然我同意在很多情况下舍入是表示层的问题,但例如,如果要计算发票总额,则可能需要在计算发票总额之前对每个发票项的总额进行舍入。如果不这样做,则打印输出可能与基于SQL的计算返回的结果不匹配。“格式总是舍入”--哦,不,它没有,例如