管理金钱列的百分比
Managing percentages of money columns
我有一个关于在 SQL 服务器中管理货币列百分比的问题。我有一个这样的简化案例:
CREATE TABLE _ROUNDERROR
(
Premium Money,
Commission Money
)
INSERT INTO _ROUNDERROR (Premium, Commission)
VALUES (1632.33, 408.08)
INSERT INTO _ROUNDERROR (Premium, Commission)
VALUES (408.08, 163.23)
当我执行以下操作时
SELECT
*,
(Commission / Premium) AS RAWDIV,
CAST(Commission AS decimal) / CAST(Premium AS decimal) AS DECDIV,
ROUND(CAST(Commission AS decimal) /CAST(Premium AS decimal), 4) AS DECDIV4,
CAST(Commission AS float) / CAST(Premium AS float) AS FLODIV,
ROUND(CAST(Commission AS float) / CAST(Premium AS float), 4) AS FLODIV4
FROM
_ROUNDERROR
这些是此查询的结果:
PREMIUM COMMISSION RAWDIV DECDIV DECDIV4 FLODIV FLODIV4
--------------------- --------------------- --------------------- --------------------------------------- --------------------------------------- ---------------------- ----------------------
1632,33 408,08 0,2499 0.2500000000000000000 0.2500000000000000000 0,249998468446944 0,25
408,08 163,23 0,3999 0.3995098039215686274 0.3995000000000000000 0,399995099000196 0,4
如上所示,如果我将钱列分开 SQL 服务器会限制结果。因此,在阅读了一些 post 之后,我尝试在将它们分开之前将两列都转换为十进制,并且它适用于第一对值(第一行)。但是小数也失去了精度(在第二行),我决定转换为浮点数(见第二行)。
好的,现在可以了,但这是最好的解决方案?有没有副作用?我无法更改字段的类型,因为它是遗留数据库。
decimal
对您不起作用的原因是因为您没有指定任何比例和精度,因此它默认为 decimal(18,0)
并通过四舍五入立即丢失任何小数部分。
CAST(1632.63 as decimal)
例如给出 1633。
您应该指定适合 money
支持的范围的精度和小数位数。
decimal(19,4)
将准确表示 922,337,203,685,477.5807
,但如果您的金钱价值永远不会接近这些限制,您可能希望降低精度。
SELECT
*,
(Commission / Premium) AS RAWDIV,
CAST(Commission AS decimal(19,4)) / CAST(Premium AS decimal(19,4)) AS DECDIV,
CAST(Commission AS float) / CAST(Premium AS float) AS FLODIV
FROM
_ROUNDERROR
Returns
+---------+------------+--------+-----------------------+-------------------+
| Premium | Commission | RAWDIV | DECDIV | FLODIV |
+---------+------------+--------+-----------------------+-------------------+
| 1632.33 | 408.08 | 0.2499 | 0.2499984684469439390 | 0.249998468446944 |
| 408.08 | 163.23 | 0.3999 | 0.3999950990001960399 | 0.399995099000196 |
+---------+------------+--------+-----------------------+-------------------+
(当然,如果您要支付 922,337,203,685,477
的佣金,我可能希望在那里找到一份工作,具体取决于货币)
我有一个关于在 SQL 服务器中管理货币列百分比的问题。我有一个这样的简化案例:
CREATE TABLE _ROUNDERROR
(
Premium Money,
Commission Money
)
INSERT INTO _ROUNDERROR (Premium, Commission)
VALUES (1632.33, 408.08)
INSERT INTO _ROUNDERROR (Premium, Commission)
VALUES (408.08, 163.23)
当我执行以下操作时
SELECT
*,
(Commission / Premium) AS RAWDIV,
CAST(Commission AS decimal) / CAST(Premium AS decimal) AS DECDIV,
ROUND(CAST(Commission AS decimal) /CAST(Premium AS decimal), 4) AS DECDIV4,
CAST(Commission AS float) / CAST(Premium AS float) AS FLODIV,
ROUND(CAST(Commission AS float) / CAST(Premium AS float), 4) AS FLODIV4
FROM
_ROUNDERROR
这些是此查询的结果:
PREMIUM COMMISSION RAWDIV DECDIV DECDIV4 FLODIV FLODIV4
--------------------- --------------------- --------------------- --------------------------------------- --------------------------------------- ---------------------- ----------------------
1632,33 408,08 0,2499 0.2500000000000000000 0.2500000000000000000 0,249998468446944 0,25
408,08 163,23 0,3999 0.3995098039215686274 0.3995000000000000000 0,399995099000196 0,4
如上所示,如果我将钱列分开 SQL 服务器会限制结果。因此,在阅读了一些 post 之后,我尝试在将它们分开之前将两列都转换为十进制,并且它适用于第一对值(第一行)。但是小数也失去了精度(在第二行),我决定转换为浮点数(见第二行)。
好的,现在可以了,但这是最好的解决方案?有没有副作用?我无法更改字段的类型,因为它是遗留数据库。
decimal
对您不起作用的原因是因为您没有指定任何比例和精度,因此它默认为 decimal(18,0)
并通过四舍五入立即丢失任何小数部分。
CAST(1632.63 as decimal)
例如给出 1633。
您应该指定适合 money
支持的范围的精度和小数位数。
decimal(19,4)
将准确表示 922,337,203,685,477.5807
,但如果您的金钱价值永远不会接近这些限制,您可能希望降低精度。
SELECT
*,
(Commission / Premium) AS RAWDIV,
CAST(Commission AS decimal(19,4)) / CAST(Premium AS decimal(19,4)) AS DECDIV,
CAST(Commission AS float) / CAST(Premium AS float) AS FLODIV
FROM
_ROUNDERROR
Returns
+---------+------------+--------+-----------------------+-------------------+
| Premium | Commission | RAWDIV | DECDIV | FLODIV |
+---------+------------+--------+-----------------------+-------------------+
| 1632.33 | 408.08 | 0.2499 | 0.2499984684469439390 | 0.249998468446944 |
| 408.08 | 163.23 | 0.3999 | 0.3999950990001960399 | 0.399995099000196 |
+---------+------------+--------+-----------------------+-------------------+
(当然,如果您要支付 922,337,203,685,477
的佣金,我可能希望在那里找到一份工作,具体取决于货币)