我想要做的是拥有前10名,但是第10名被称为“其他”,其中所有内容的总和位于其中的前9位且总数为10。所以基本上它看起来像这样:
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行是“其他”,所有内容都排在前9位,并且最后还包括总数?
答案 0 :(得分: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
答案 1 :(得分: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]