繁体   English   中英

使用聚合函数时,带有CASE的SELECT失败

[英]SELECT with CASE fail when aggregate function is used

我有以下t-sql查询。

DECLARE @Test TABLE(
    Points INT
    ,PointsOf INT
)
INSERT INTO @Test
VALUES (3,12),(2,12),(3,12),(11,12),(12,12),(5,12),(0,12)

DECLARE @Decimal TINYINT = 2


SELECT  
    CASE @Decimal
        WHEN 0 THEN CAST(CAST(SUM(Points) AS DECIMAL(18,0)) / NULLIF(SUM(PointsOf), 0) * 100 AS DECIMAL(18,0))
        WHEN 1 THEN CAST(CAST(SUM(Points) AS DECIMAL(18,1)) / NULLIF(SUM(PointsOf), 0) * 100 AS DECIMAL(18,1))
        WHEN 2 THEN CAST(CAST(SUM(Points) AS DECIMAL(18,2)) / NULLIF(SUM(PointsOf), 0) * 100 AS DECIMAL(18,2))
    END  AS Score
FROM @Test

我有一个变量@Decimals 当变量为0时,我需要查询以XX格式返回分数,以XX.X格式返回1,以XX.XX格式返回2。 此处发生的情况是CASE输入了多个THEN子句。 执行上面的查询时,我得到44.86的结果是正确的,但是当我将@Decimals变量更改为0时,我得到的结果44.00是不正确的。 它假定只返回44个不带小数的位置。 当我的@Decimals为1时,会发生相同的事情,当它必须为44.9时,它将返回44.90。

有谁知道为什么会这样吗?

我不知道MS Server的工作方式,但是根据ANSI SQL规范,一列始终具有一种特定的数据类型,在这种情况下,该数据类型为小数(20,2),即可以存储所有数据的最小数据类型。案例的不同结果类型。

正如jarlh正确指出的那样,case语句将其转换为最小的数据类型以容纳所有结果类型。 (请参阅MSDN文档 ,特别是“ 返回类型”部分)

在我看来,这仅仅是一个显示问题。 @decimal变量设置为1时,要显示44.9而不是44.90 (注意尾随零)。

一种方法是在varchar中添加一个额外的强制类型转换。 这不是很漂亮,也不是我建议做的事情,但是如果您坚持要在SQL Server中进行格式化和UI键入操作,那该怎么办?

DECLARE @Test TABLE(
    Points INT
    ,PointsOf INT
)
INSERT INTO @Test
VALUES (3,12),(2,12),(3,12),(11,12),(12,12),(5,12),(0,12)

DECLARE @Decimal TINYINT = 1


SELECT  
    CASE @Decimal
        WHEN 0 THEN cast(Cast(CAST(SUM(Points) AS DECIMAL(18,0)) / NULLIF(SUM(PointsOf), 0) * 100 as decimal(18,0)) as varchar(10))
        WHEN 1 THEN cast(Cast(CAST(SUM(Points) AS DECIMAL(18,1)) / NULLIF(SUM(PointsOf), 0) * 100 as decimal(18,1))as varchar(10))
        WHEN 2 THEN cast(Cast(CAST(SUM(Points) AS DECIMAL(18,2)) / NULLIF(SUM(PointsOf), 0) * 100 as decimal(18,2))as varchar(10))
    END  AS Score
FROM @Test

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM