0

我想做的是有一个前 10 名,但第 10 个条目被称为“其他”,其中所有内容的总和前 9 名的总和有一个总数。所以基本上它看起来像这样:

ReportingDate   FundCode    Currency            Duration Contribution   Percentage
31/10/2012      1111        Malaysian Ringgit   0.5                     14.6
31/10/2012      1111        Turkish Lira        0.3                     13.5
31/10/2012      1111        Russian Rouble      0.5                     11.9
31/10/2012      1111        Indunesian Rupiah   0.6                     11.7
31/10/2012      1111        Mexican Peso        0.6                     11.7
31/10/2012      1111        Polish Zloty        0.3                     10.2
31/10/2012      1111        Mexican Peso        0.4                     10.1
31/10/2012      1111        Polish Zloty        0.3                      9.9
31/10/2012      1111        South African Rand  0.2                      5.8
31/10/2012      1111        Brazilian Real      0.3                      2.0
31/10/2012      1111        Other               0.6                     -1.4
31/10/2012      1111        Total               4.6                    100.0

我的代码目前如下所示:

;;WITH CTE AS
(
SELECT 
    ReportingDate
,   PortfolioID
,   DV.dmv_nme AS Currency
,   RANK() OVER (PARTITION BY PortfolioID ORDER BY SUM(Percentage) DESC) AS [Rank]
,   ISNULL(CAST(SUM(DurationContribution)/100.0 AS DECIMAL(22,1)),0)    AS [Duration Contribution]
,   CAST(SUM(Percentage) AS DECIMAL(22,1))  AS [Weight]

FROM @Worktable as WT

INNER JOIN dw_domain_value AS DV
    ON DV.dmv_value = WT.Currency
    AND DV.data_cls_num = 2

GROUP BY    WT.ReportingDate
    ,   WT.PortfolioID
    ,   DV.dmv_nme
)

SELECT 
ReportingDate
, PortfolioID
, Currency
, [Rank]
, [Duration Contribution]
, [Weight]
FROM CTE
WHERE [Rank] <= 10
ORDER BY ReportingDate, PortfolioID, [Rank], [Weight] DESC

所以这给了我前10名的罚款。那么我怎么能得到它,以便最后的第 10 行是“其他”,除了前 9 行之外的所有内容,最后还包括总数?

4

2 回答 2

0

这是一种解决方案。但是您可以将其移至 CTE 以获得更好的性能。

;;WITH CTE AS
(
SELECT 
ReportingDate
,PortfolioID
,DV.dmv_nme AS Currency
,RANK() OVER (PARTITION BY PortfolioID ORDER BY SUM(Percentage) DESC) AS [Rank]
,ISNULL(CAST(SUM(DurationContribution)/100.0 AS DECIMAL(22,1)),0) AS [Duration Contribution]
,CAST(SUM(Percentage) AS DECIMAL(22,1))  AS [Weight]

FROM @Worktable as WT

INNER JOIN dw_domain_value AS DV
ON DV.dmv_value = WT.Currency
AND DV.data_cls_num = 2

GROUP BY    WT.ReportingDate
,   WT.PortfolioID
,   DV.dmv_nme
)    

SELECT 
ReportingDate
, PortfolioID
, CASE WHEN [Rank] <= 10 THEN Currency ELSE 'Total' END As Currency
, SUM([Duration Contribution]) As [Duration Contribution]
, SUM([Weight]) As [Weight]
FROM CTE
GROUP BY
ReportingDate
, PortfolioID
, CASE WHEN [Rank] <= 10 THEN Currency ELSE 'Total' END As Currency
WITH ROLLUP
ORDER BY ReportingDate, PortfolioID, [Rank], [Weight] DESC
于 2012-11-23T05:05:11.643 回答
0

为此,我决定不能使用 CTE,因此最终不得不将这些部分逐节插入临时表中,如下所示:

/* Include only top 9 */
INSERT INTO @FinalOutput
SELECT 
        ReportingDate
    ,   PortfolioID
    ,   PortfolioNme
    ,   Currency
    ,   [Rank]
    ,   DurationContribution
    ,   [Weight]
FROM @WorktableGrouped

WHERE [Rank] <= 9

ORDER BY ReportingDate, PortfolioID, [Rank], [Weight] DESC

/* Aggregate everything outside the top 9 into other */
INSERT INTO @FinalOutput
SELECT 
        ReportingDate
    ,   PortfolioID
    ,   PortfolioNme
    ,   'Other'         AS Currency
    ,   10              AS [Rank]
    ,   SUM(DurationContribution) AS DurationContribution
    ,   SUM([Weight])   AS [Weight]
FROM @WorktableGrouped

WHERE [Rank] > 9

GROUP BY ReportingDate, PortfolioID, PortfolioNme

ORDER BY ReportingDate, PortfolioID, [Rank], [Weight] DESC

SELECT * FROM @FinalOutput

/* Final Select with roll up for total per portfolio */
SELECT 
    ReportingDate
,   PortfolioID
,   PortfolioNme

,   CASE 
        WHEN GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Currency, [Rank]) = 3 THEN 'Total'
        ELSE Currency
    END                                                         AS Currency

,   CASE 
        WHEN GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Currency, [Rank]) = 3 THEN 11
        ELSE [Rank]
    END                                                         AS [Rank]

,   ISNULL(CAST(SUM(DurationContribution) AS DECIMAL(22,1)),0)  AS [Duration Contribution]  
,   CAST(SUM([Weight]) AS DECIMAL(22,1))                        AS [Weight]
--, GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Currency, [Rank])

FROM @FinalOutput

GROUP BY ReportingDate
, PortfolioID
, PortfolioNme
, Currency
, [Rank] WITH ROLLUP

HAVING GROUPING_ID(ReportingDate, PortfolioID, PortfolioNme, Currency, [Rank]) IN (0,3)

ORDER BY ReportingDate, PortfolioID, [Rank]
于 2012-12-05T11:21:18.280 回答