2012-06-15 59 views
2

我的最终目的是为了有一个表,看起来像这样:如何分组数据正确

Maturity Band  AAA  AA  A A- BBB+  BBB- BB+ BB Total 
Less Than 1 yr 2.63% 5%    2%       9.63% 
1 to 5 yrs      5%   5%       10% 
5 to 10 yrs  5.00%        5%     10% 
10 to 20 yrs       2%         2% 
More than 20 yrs 10%           6% 1% 17% 
Total    17.63% 5% 5% 2% 7%  5%  6% 1% 48.63% 

在我的程序(@Worktable)表我已经创建了这个样子的:

PortfolioID IssueName SandPRating SandPRatingSort MaturityBand MaturitySort 
XXXXX   Bond1  AAA   1     Less than 1 yr 1 
XXXXX   Bond2  AAA   1     Less than 1 yr 1 
XXXXX   Bond3  AA-   7     5 to 10 yrs  3 
XXXXX   Bond4  BBB+   8     1 to 5 yrs  2 
etc....... 

SandPRatingSort命令的评分最高,其中1为最高,而对于成熟度排序则相同。

我的问题是,我在上面的格式中编写表格的代码(对不起,如果这看起来很简单,但我相对比较新)。我可以通过MaturityBand对它进行分组,但是如何将它按照正确的顺序进行分类,以及如何使用分级作为标题来实现百分比?顺便提一下,百分比就是投资组合持有评级占所有债券百分比的债券数量。

最好到目前为止,我得到的是这个支点:

SELECT MaturityBand, [AAA],[AA+],[AA],[AA-],[A+],[A],[A-],[BBB+],[BBB],[BBB-],[BB+],[BB],[BB-],[B+],[B],[B-],[CCC+],[CCC],[CCC-],[CC],[C],[DDD],[DD],[D],[N.R.],[N.A.],[WR] 
FROM 
(
SELECT 
MaturityBand 
,SandPRating 
FROM @Worktable 
WHERE SandPRating IS NOT NULL 
GROUP BY MaturityBand, SandPRating, MaturitySort, SandPSort 
) AS source 
PIVOT 
(
COUNT(SandPRating) 
FOR SandPRating IN ([AAA],[AA+],[AA],[AA-],[A+],[A],[A-],[BBB+],[BBB],[BBB-],[BB+],[BB],[BB-],[B+],[B],[B-],[CCC+],[CCC],[CCC-],[CC],[C],[DDD],[DD],[D],[N.R.],[N.A.],[WR]) 
) AS pvt 

枢转不做我现在想要做什么。我如何得到百分比?我怎样才能得到列和行的总计?此外,数据透视中的计数仅返回1,我怎样才能得到这个总和每列的评级数量,而无需对工作表做一个整体的重新加载?

正确的方向或某些指导的一个点将大大appreaciated。

感谢

+0

应该不是“合计合计”值是100 %而不是48.63%? (我只是想正确理解你的百分比值背后的逻辑。) –

+0

是的,它应该总计100%,只是很快就试图写出一些测试数据。 –

+0

这个百分比应该用债券价值加权,还是真的只是计算持有量? – AakashM

回答

1

带着几分试验和错误和一些帮助从其他职位我已经成功地回答我的问题。 CTE是非常有用的,我很高兴我有这样的经验能够学习它的来龙去脉。

;WITH CTE 
AS 
(
SELECT PortfolioID 
     , MaturityBand 
     , SandPRating 
     , MaturitySort 
     , SUM((1/RecNo)*100) AS Pct 

FROM @Worktable AS A 
--WHERE SandPRating IS NOT NULL 
Group by MaturitySort, MaturityBand, SandPRating, PortfolioID 

UNION All 

SELECT PortfolioID 
     , MaturityBand 
     , 'SandPRating_Total' AS SandPRating 
     , MaturitySort 
     , COUNT(*) * 100.0 
     /
     (
      SELECT COUNT(*) 
      FROM  @Worktable AS B 
      WHERE B.PortfolioID = A.PortfolioID 
     ) AS Total_Pct 
FROM @Worktable AS A 
--WHERE SandPRating IS NOT NULL 
GROUP BY MaturitySort, MaturityBand, PortfolioID 
) 
, CTE2 
AS 
(
SELECT Grouping_ID(SandPRating, MaturityBand, MaturitySort) AS ID 

    , CASE 
     WHEN Grouping_ID(SandPRating, MaturityBand, MaturitySort) = 3 THEN 'Total' 
     ELSE MaturityBand 
     END            AS MaturityBand 

    , SandPRating 

    , CASE 
     WHEN Grouping_ID(SandPRating, MaturityBand, MaturitySort) = 3 THEN 1000 
     ELSE MaturitySort 
     END            AS MaturitySort 

    , SUM(Pct) AS PCT 

FROM CTE 
GROUP BY ROLLUP (SandPRating 
    , MaturityBand 
    , MaturitySort) 
) 
--PIVOT 
SELECT MaturityBand, [AAA],[AA+],[AA],[AA-],[A+],[A],[A-] 
    ,[BBB+],[BBB],[BBB-],[BB+],[BB],[BB-],[B+],[B],[B-] 
    ,[CCC+],[CCC],[CCC-],[CC],[C],[DDD],[DD],[D],[N.R.] 
    ,[N.A.],[WR],[Unass],[SandPRating_Total]  
FROM ( SELECT SandPRating, MaturityBand, MaturitySort, PCT 
     FROM Cte2 
     WHERE ID = 0 or ID = 3 
    ) AS x 

PIVOT (SUM(PCT) 
     FOR SandPRating 
     IN ([AAA],[AA+],[AA],[AA-],[A+],[A],[A-] 
      ,[BBB+],[BBB],[BBB-],[BB+],[BB],[BB-],[B+],[B],[B-] 
      ,[CCC+],[CCC],[CCC-],[CC],[C],[DDD],[DD],[D],[N.R.] 
      ,[N.A.],[WR],[Unass],[SandPRating_Total]) 
    ) myPiv 
ORDER BY MaturitySort 
0

下得到所有的总数计算百分比值的所有项目:

SELECT * 
FROM (
    SELECT 
    MaturitySort = COALESCE(MaturitySort, 2147483647), 
    MaturityBand = COALESCE(MaturityBand, 'Total'), 
    SandPRating = COALESCE(SandPRating , 'Total'), 
    [Percent] = 
     COUNT(*) * 100.0/
     SUM(CASE WHEN MaturityBand IS NOT NULL AND SandPRating IS NOT NULL THEN COUNT(*) END) OVER() 
    FROM WorkTable 
    GROUP BY 
    CUBE(
    (MaturityBand, MaturitySort), 
    (SandPRating) 
) 
) s 
PIVOT (
    MAX([Percent]) FOR SandPRating IN (
    [AAA],[AA+],[AA],[AA-],[A+],[A],[A-], 
    [BBB+],[BBB],[BBB-],[BB+],[BB],[BB-],[B+],[B],[B-], 
    [CCC+],[CCC],[CCC-],[CC],[C],[DDD],[DD],[D],[N.R.], 
    [N.A.],[WR],[Unass],[Total] 
) 
) p 
ORDER BY MaturitySort 

正如你所看到的,百分比值的计算使用聚合开窗函数(SUM())。如果没有CUBE()的分组,我们可以只做SUM(COUNT(*)) OVER()。但与CUBE()它将包括不应包括的值(卷起计数)。并且解决这些问题的一种方法是对NULL进行测试SandPRatingMaturityBand,因为当行包含卷起计数时,NULL会替换其中一个或两个列。

当然,假定列MaturityBand都不能保存实际的NULL。在总如果返回0为两列,包括COUNT(*):省略卷功能更恰当的方式或许会被测试的GROUPING(column)的结果,而不是

… 
[Percent] = 
    COUNT(*) * 100.0/
    SUM(CASE WHEN GROUPING(MaturityBand) = 0 AND GROUPING(SandPRating) = 0 THEN COUNT(*) END) OVER() 
…