ROUND TSQL - .5 不四舍五入

ROUND TSQL - .5 not rounding up

在我的 select 语句中,我有以下 case 语句,我需要将其四舍五入到小数点后 0 位到 return 一个 INT:

SELECT 
        ReportingDate
    ,   PortfolioID
    ,   PortfolioNme
    ,   '16'                                                                AS [Rank]
    ,   'Average credit rating'                                             AS Rating
    ,   ROUND(SUM((Percentage * CASE
                                    WHEN WT.IssueType1 IN ('050','110') THEN 15.5
                                    ELSE xref.internal_value2
                                END ))/SUM(Percentage),0)   AS [Weight]

FROM @WorktableSA as WT

    LEFT OUTER JOIN DP_CrossReference AS xref
        ON xref.internal_value = WT.Rating
        AND xref.codeset_type_id = 10013
        AND xref.originator_id = 'KurtosysExtract'          

GROUP BY    WT.ReportingDate
        ,   WT.PortfolioID
        ,   WT.PortfolioNme


ORDER BY    WT.ReportingDate
        ,   WT.PortfolioID

有一个特定的结果 returned 是不正确的。 ROUND前的SUM中itreturns的值为15.5。但是 ROUND return 的值为 15,而我希望将其四舍五入为 16。

为了深入了解数据类型,Percentage 是一个 FLOAT,internal_value2 是一个 NVARCHAR,它混合了 INT (1,2,3) 和一位小数 (15.5)。

我已经尝试将所有值修改为浮点数,但我仍然得到 15。我什至做了以下操作,它 returns 16:

SELECT ROUND(15.5,0)

在尝试测试替代方案方面的任何帮助将不胜感激,因为我现在没有想法了?

  1. 有round函数就可以了,SELECT ROUND(15.5,0)会return16

但是,例如,如果需要舍入从 0.391 的值(在你的示例中可以是 15.4916)然后使用下面的方法

DECLARE @val AS FLOAT = 15.49

SELECT ( CASE WHEN @val - CONVERT(INT, @val) >= 0.49
                    THEN CEILING(@val)
              ELSE ROUND(@val, 0)  END )   AS NewVal

此变体也适用,但从 2012 版本开始

SELECT IIF( @val - CONVERT(INT, @val) >= 0.49, CEILING(@val), ROUND(@val, 0))  AS NewVal

所以你的最终查询应该是这样的:

SELECT T.ReportingDate
      ,T.PortfolioID
      ,T.PortfolioNme
      ,T.[Rank]
      ,T.Rating
      ,(CASE    WHEN T.[Weight] - CONVERT(INT, T.[Weight]) >= 0.49
                THEN CEILING(T.[Weight])
                ELSE ROUND(T.[Weight], 0) END) AS [Weight]
FROM (   SELECT ReportingDate
               ,PortfolioID
               ,PortfolioNme
               ,'16' AS [Rank]
               ,'Average credit rating' AS Rating
               ,ROUND(SUM((Percentage * CASE WHEN WT.IssueType1 IN ('050','110')
                                             THEN 15.5
                                             ELSE xref.internal_value2 END)) 
                        / SUM(Percentage), 0) AS [Weight]
         FROM @WorktableSA AS WT
                    LEFT OUTER JOIN DP_CrossReference AS xref 
                            ON xref.internal_value = WT.Rating
                                AND xref.codeset_type_id = 10013
                                AND xref.originator_id = 'KurtosysExtract'
        GROUP BY WT.ReportingDate
                ,WT.PortfolioID
                ,WT.PortfolioNme
    ) AS T
ORDER BY T.ReportingDate
        ,T.PortfolioID

  1. 如果您遇到这样的问题SELECT ROUND(15.49999,0)那么这个方法会帮助您

    DECLARE @val AS FLOAT = 15.49999
    
    SELECT ROUND(CONVERT(NUMERIC(15,1),@val),0)
    

这将 return 16

所以,你的最终查询应该是这样的

SELECT 
        ReportingDate
    ,   PortfolioID
    ,   PortfolioNme
    ,   '16'                                                                AS [Rank]
    ,   'Average credit rating'                                             AS Rating
    ,   ROUND(CONVERT(NUMERIC(15,1),SUM((Percentage * CASE
                                    WHEN WT.IssueType1 IN ('050','110') THEN 15.5
                                    ELSE xref.internal_value2
                                END ))/SUM(Percentage)),0)   AS [Weight]

FROM @WorktableSA as WT

    LEFT OUTER JOIN DP_CrossReference AS xref
        ON xref.internal_value = WT.Rating
        AND xref.codeset_type_id = 10013
        AND xref.originator_id = 'KurtosysExtract'          

GROUP BY    WT.ReportingDate
        ,   WT.PortfolioID
        ,   WT.PortfolioNme

我认为这是一个错误。

试试这个,它不会按预期工作:

declare @dd float

select @dd = 375.45
select @dd,ROUND(@dd,1)

结果是

375.45  375.4