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,我怎样才能得到它来计算每列的评分数,而不必对工作表进行大量的返工?

对正确方向的一点或一些指导将不胜感激。

谢谢

4

2 回答 2

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
于 2012-06-19T10:15:58.170 回答
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()它会包含不应包含的值(汇总计数)。解释它们的一种方法是测试SandPRatingMaturityBandNULL,因为当行包含汇总计数时,NULL 被替换为任一列或两列。

当然,这假设任何一个列MaturityBand都不能保存实际的 NULL。省略汇总的更合适的方法可能是测试结果:如果它为两列都返回,则在总数中包括:GROUPING(column)0COUNT(*)

…
[Percent]    =
  COUNT(*) * 100.0 /
  SUM(CASE WHEN GROUPING(MaturityBand) = 0 AND GROUPING(SandPRating) = 0 THEN COUNT(*) END) OVER ()
…
于 2012-06-22T20:04:17.860 回答