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()含まれるべきではない値が含まれます (ロールアップされたカウント)。行にロールアップされたカウントが含まれる場合、いずれかまたは両方の列が NULL に置き換えられるため、それらを説明する 1 つの方法は、NULL をSandPRatingテストすることです。MaturityBand

もちろん、どちらの列も、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 に答える