2013-03-08 15 views
1

我爲與下面的腳本結束一些管理信息的報告建立一個前10名:阿爾特十大時四捨五入到1位小數等於100

IF @ReportType = 'SectorEQ' 

BEGIN 
/* Final Select with roll up for total per portfolio */ 
    SELECT 
      CONVERT(VARCHAR, ReportingDate, 103) AS ReportingDate 
     , PortfolioID        AS FundCode 
     , PortfolioNme       AS FundName 

     , CASE 
       WHEN GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Sector, [Rank], [Weight]) = 7 THEN 'Total' 
       ELSE Sector 
       END         AS Sector 

     , CASE 
       WHEN GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Sector, [Rank], [Weight]) = 7 THEN 102 
       ELSE [Rank] 
      END          AS [Rank] 

     , CAST(SUM([Weight]) AS DECIMAL(22,1)) AS Percentage 

    FROM @FinalOutputEQ_CS 

    GROUP BY ReportingDate 
      , PortfolioID 
      , PortfolioNme 
      , Sector 
      , [Rank] 
      , [Weight] WITH ROLLUP 

    HAVING GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Sector, [Rank], [Weight]) IN (1,7) 

    ORDER BY ReportingDate 
      , PortfolioID 
      , [Rank] 

正如你所看到的,百分比四捨五入到小數點後一位,這可能會導致四捨五入問題,因爲百分比與小數點後一位的總和可能小於或大於100,即100.1或99.9。我需要做的是確保四捨五入到小數點後1位的百分比都等於100.0。

我想要做的就是檢查一下,如果不是採用Top 1並減去其百分比的差值,則舍入百分比的總和等於100.0。

我對如何做到這一點有一些想法,但我想知道什麼纔是確保這個快速高效運行而不會減慢proc下降的最佳方法?

編輯:示例表

ReportingDate FundCode FundName Sector     Rank Percentage 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Consumer Discretionary  1 16.1 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Health Care     2 13.8 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Information Technology  3 11.8 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Telecommunication Services 4 10.3 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Consumer Staples   5 10.1 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Industrials     6 8.7 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Financials     7 6.8 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Materials     8 6.5 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Energy      9 5.2 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Utilities     10 0.7 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Cash and Bonds    101 10.1 
28/02/2013 XXXXXXXX XXXXXXXXXXXXXXX Total      102 100.1 

回答

0

唯一的解決辦法我能制定出這是創建以下基本上總結了細節給一個總的腳本。然後在我的CTE我從頭1減去了這個和總數:

IF @ReportType = 'SectorEQ' 

BEGIN 
    INSERT INTO @RoundingDifference 
     SELECT 
       PortfolioID 
      , CAST(SUM([Weight])-100 AS DECIMAL(22,1)) AS [Weight] 

     FROM @FinalOutputEQ_CS 

     WHERE Sector <> 'Total' 

     GROUP BY   
       ReportingDate 
      , PortfolioID 
      , PortfolioNme 

END 

IF @ReportType = 'SectorEQ' 

BEGIN 
;;WITH CTE AS 
    (
/* Final Select with roll up for total per portfolio */ 
    SELECT 
      CONVERT(VARCHAR, ReportingDate, 103) AS ReportingDate 
     , PortfolioID        AS FundCode 
     , PortfolioNme       AS FundName 

     , CASE 
       WHEN GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Sector, [Rank], [Weight]) = 7 THEN 'Total' 
       ELSE Sector 
       END         AS Sector 

     , CASE 
       WHEN GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Sector, [Rank], [Weight]) = 7 THEN 102 
       ELSE [Rank] 
      END          AS [Rank] 

     , CAST(SUM([Weight]) AS DECIMAL(22,1)) AS Percentage 

    FROM @FinalOutputEQ_CS 

    GROUP BY ReportingDate 
      , PortfolioID 
      , PortfolioNme 
      , Sector 
      , [Rank] 
      , [Weight] WITH ROLLUP 

    HAVING GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Sector, [Rank], [Weight]) IN (1,7) 
    ) 
    SELECT 
     ReportingDate 
    , FundCode 
    , FundName 
    , Sector 
    , [Rank] 

    , CASE 
      WHEN [Rank]IN (1,102) THEN Percentage - RD.[Weight] 
      ELSE Percentage 
     END  AS Percentage 

    FROM CTE AS CTE 

     INNER JOIN @RoundingDifference AS RD 
     ON RD.PortfolioID = CTE.FundCode 

    ORDER BY ReportingDate 
      , FundCode 
      , [Rank] 

END 
0

可能纔剛剛沒有小數類型去第十位?

EG:

declare @decimal decimal (16,4) = 123456.7890; ; 

select cast(@decimal as decimal(16,0)) 

INSTEAD OF

select cast(@decimal as decimal(16,1)) 

而且你爲什麼具有價值出去22個值? (十進制類型的第一個位置)如果您擔心proc的高效性,那麼這就是很多要存儲的數據。我通常對第一個數字很吝嗇,除非有非常大的數據回報,否則很少超過16。

編輯四捨五入第十名:

declare @decimal decimal (16,1) = 123456.5; -- you can change this as needed to see how it will change 

-- if you want to do rounding then you need to determine if the tenth position is above or greater than five 
-- you could do this in a function if you want. You need to determine a return of 1 or 0 based on rounding 
declare @logic int = case when right(@decimal,1) >= 5 then 1 else 0 end 

-- find the integer value WITHOUT the decimal places and then add the logic variable 
select left(@decimal, len(@decimal) - 2) + @logic as Rounded 
+0

感謝您的答覆。我需要它去1個小數位。我想可能是將100與所有百分比之和的差值存儲到一個變量的一位小數位,然後選擇最終表的前1並從頂部刪除差異? – 2013-03-11 10:06:49

+0

查看更新,它可能會解決您的問題 – djangojazz 2013-03-11 16:39:21

+0

我已經爲我的問題添加了一個示例表。所以你會看到總數是100.1,這是由於四捨五入的問題。因此,我們將確定需要從頂部1中刪除0.1,從而使得16.0而不是16.1。我不明白你的回答能夠解決我的問題嗎?你能解釋更多嗎? (對於昏暗的抱歉) – 2013-03-12 09:43:29