意外的SQL除法结果?
我使用SQL Server 通过与部门合作,我在这两个查询中收集了我的发现,您可以使用SQL Server版本重现这两个查询 我希望在这两种情况下,带整数的除法都有相同的值。 因为不管我的表中的值如何,如果我得到意外的结果,我最终会遇到一个逻辑错误,有时很难调查 sqla:意外的SQL除法结果?,sql,sql-server-2008,division,Sql,Sql Server 2008,Division,我使用SQL Server 通过与部门合作,我在这两个查询中收集了我的发现,您可以使用SQL Server版本重现这两个查询 我希望在这两种情况下,带整数的除法都有相同的值。 因为不管我的表中的值如何,如果我得到意外的结果,我最终会遇到一个逻辑错误,有时很难调查 sqla: WITH s AS ( SELECT 'Integer' AS c, 1 AS k UNION SELECT 'Float', 1 UNION SELECT 'NULL', NULL ) SELEC
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', 1 UNION
SELECT 'NULL', NULL
)
SELECT
c AS [Type],
k/10 AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
COALESCE(k, 0)/10 AS 'Coalesce',
COALESCE(k, .0)/10 AS 'Coalesce with float'
FROM s;
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', .1 UNION
SELECT 'NULL', NULL
)
SELECT
c AS [Type],
k/10 AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
COALESCE(k, 0)/10 AS 'Coalesce',
COALESCE(k, .0)/10 AS 'Coalesce with float'
FROM s;
结果A
Type Division Cast Coalesce Coalesce with float
Float 0 0.100000 0 0.100000
Integer 0 0.100000 0 0.100000
NULL NULL NULL 0 0.000000
Type Division Cast Coalesce Coalesce with float
Float 0.010000 0.010000 0.010000 0.010000
Integer 0.100000 0.100000 0.100000 0.100000
NULL NULL NULL 0.000000 0.000000
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', 1 UNION
SELECT 'NULL', NULL
)
SELECT c AS [Type],
FLOOR(k/10) AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
FLOOR(COALESCE(k, 0)/10) AS 'Coalesce',
COALESCE(k, .0)/10 AS 'Coalesce with float'
FROM s;
SQL B:
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', 1 UNION
SELECT 'NULL', NULL
)
SELECT
c AS [Type],
k/10 AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
COALESCE(k, 0)/10 AS 'Coalesce',
COALESCE(k, .0)/10 AS 'Coalesce with float'
FROM s;
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', .1 UNION
SELECT 'NULL', NULL
)
SELECT
c AS [Type],
k/10 AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
COALESCE(k, 0)/10 AS 'Coalesce',
COALESCE(k, .0)/10 AS 'Coalesce with float'
FROM s;
结果A
Type Division Cast Coalesce Coalesce with float
Float 0 0.100000 0 0.100000
Integer 0 0.100000 0 0.100000
NULL NULL NULL 0 0.000000
Type Division Cast Coalesce Coalesce with float
Float 0.010000 0.010000 0.010000 0.010000
Integer 0.100000 0.100000 0.100000 0.100000
NULL NULL NULL 0.000000 0.000000
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', 1 UNION
SELECT 'NULL', NULL
)
SELECT c AS [Type],
FLOOR(k/10) AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
FLOOR(COALESCE(k, 0)/10) AS 'Coalesce',
COALESCE(k, .0)/10 AS 'Coalesce with float'
FROM s;
您的第一个表是所有整数
选择“Float”,1是一个INT
不是一个Float,仅仅因为你把单词放在那里。它将被暗示为INT,因为没有小数点
然后,你知道整数除法使用整数。。。例如
select 3/10
是0,而不是用select 3/10.0
得到的.3000。如果希望返回十进制/浮点,则分子或分母必须是浮点(或两者都是)
编辑
在你最后的评论之后,我更加理解你的问题。当您将不同的数据类型合并在一起时(您在第二个CTE
中执行了此操作),SQL Server将隐式地将它们转换为必要的数据类型,以伴随所有输入
所以,如果你从cte中选择*。。。您将看到您的1已转换为1.0。一个列只能有一个数据类型。在本例中,SQL Server必须选择INT
或FLOAT
。如果选择INT,则会出现数据完整性问题
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', .1 UNION
SELECT 'NULL', NULL
)
select * from s
如果希望这两个数据集的结果相同,请使用FLOOR()函数 SQL A
Type Division Cast Coalesce Coalesce with float
Float 0 0.100000 0 0.100000
Integer 0 0.100000 0 0.100000
NULL NULL NULL 0 0.000000
Type Division Cast Coalesce Coalesce with float
Float 0.010000 0.010000 0.010000 0.010000
Integer 0.100000 0.100000 0.100000 0.100000
NULL NULL NULL 0.000000 0.000000
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', 1 UNION
SELECT 'NULL', NULL
)
SELECT c AS [Type],
FLOOR(k/10) AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
FLOOR(COALESCE(k, 0)/10) AS 'Coalesce',
COALESCE(k, .0)/10 AS 'Coalesce with float'
FROM s;
SQL B
WITH s AS (
SELECT 'Integer' AS c, 1 AS k UNION
SELECT 'Float', .1 UNION
SELECT 'NULL', NULL
)
SELECT
c AS [Type],
FLOOR(k/10) AS 'Division',
CAST(k as numeric(38,4))/10 AS 'Cast',
FLOOR(COALESCE(k, 0)/10) AS 'Coalesce',
COALESCE(FLOOR(k), .0)/10 AS 'Coalesce with float'
FROM s;
两个查询的结果
Type Division Cast Coalesce Coalesce with float
Float 0 0.100000 0 0.100000
Integer 0 0.100000 0 0.100000
NULL NULL NULL 0 0.000000
请检查第二条语句,选择“Float”。1@profimedica在第二条语句中,有一个小数点。与0.1相同。这在第一个例子中是不存在的,这就是整数除法返回整数的原因。我必须强调的是,我创建这两个场景时要注意添加点以创建浮点的效果。另外,我希望整数除法的结果是一个整数,浮点运算的结果是一个浮点运算。这是两个示例中第一行的情况。意外的结果出现在整数行上,其中参与者相同,但输出类型由浮点结果决定。在SQL B中,floor结果是一个整数,由oalesce:COALESCE(floor(k),.0)转换回浮点。实际上,您的方法将强制结果的类型,scsimon解释说,类型优先级tah是为整个列决定的。