2017-09-05 51 views
2

我使用SQL Server。意外的SQL分割结果?

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

我期待从Integer公司获得相同的价值。 因为无论我的表中有什么值,如果我得到意想不到的结果,我最终会遇到一个逻辑错误,有时很难进行调查。

SQL答:

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 

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; 

结果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 

回答

5

你的第一张表是所有整数。

SELECT 'Float', 1 is an INT仅仅因为您将单词放在那里而不是浮动。由于没有小数位,因此它将被隐含为INT。

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

select 3/10是0,而不是0.3000,你将与select 3/10.0得到。如果你想返回小数/浮动,要么分子或分母需要一个浮动(或两者)

编辑

你最后的评论后,我明白你的问题更多。当你将不同的数据类型结合在一起时,你在第二个CTE中做了什么,SQL Server将隐式地将它们转换为所有输入所需的数据类型。 See the order of precedence here

所以,如果你只是从那个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 
+0

请检查第二条语句SELECT'Float',.1 – profimedica

+1

@profimedica在第二条语句中,您有一个小数点。这与0.1相同。第一个是缺失的,这就是为什么你的整数除法返回一个整数。 – scsimon

+1

我必须强调,我创建了两个方案,意识到添加点创建浮动的效果。此外,我期待的整数除法的结果导致一个整数和浮动的结果导致浮动。这两个例子都是第一行。意想不到的结果是在整数线上,参与者是相同的,但输出的类型是由浮点结果决定的。 – profimedica

1

如果你想拥有这两个数据集相同的结果,使用FLOOR()函数

SQL一个

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乙

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 
+1

在您的SQL B层结果中,通过oalesce:COALESCE(FLOOR(k),.0)转换回浮动的整数。事实上,你的方法会强制结果类型,scsimon解释了类型优先级tah决定整个列。 – profimedica