意外的SQL除法结果?

pro*_*ica 2 sql division sql-server-2008

我使用SQL Server.

与分部合作我在这两个您可以使用SQL Server版本重现的查询中收集了我的发现.

我希望Division with Integer在这两种情况下具有相同的值.因为无论我的表中的值如何,如果我得到意想不到的结果,我最终会得到一个逻辑错误,有时很难调查.

SQL A:

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; 
Run Code Online (Sandbox Code Playgroud)

结果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
Run Code Online (Sandbox Code Playgroud)

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; 
Run Code Online (Sandbox Code Playgroud)

结果A.

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
Run Code Online (Sandbox Code Playgroud)

scs*_*mon 5

你的第一个表是全部整数.

SELECT 'Float', 1 is an INT不是因为你把这个词放在那里而浮动.它将隐含为INT,因为没有小数位.

然后,你知道整数除法使用整数......例如......

select 3/10是0而不是.3000,你会得到select 3/10.0.如果要返回decimal/float,则分子或分母需要是float(或两者)

编辑

在您上次发表评论后,我更了解您的问题.当您将不同的数据类型组合在一起时,您在第二步中将它们联合起来,CTESQL Server将隐式地将它们转换为必要的数据类型以伴随所有输入.请在此处查看优先顺序

所以,如果你只是从那个cte中选择*,你会看到你的1被转换为1.0.列只能有一种数据类型.在此示例中,SQL Server必须选择INTFLOAT.如果选择了INT,则会出现数据完整性问题.

WITH s AS (
    SELECT 'Integer' AS c, 1 AS k UNION
    SELECT 'Float', .1 UNION
    SELECT 'NULL', NULL
) 

select * from s
Run Code Online (Sandbox Code Playgroud)