我的最终目标是拥有一张如下表:
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,如何在不对工作台进行全部工作的情况下对每列的额定值进行求和?
正确方向上的一点或一些指导将会大大增加。
由于
答案 0 :(得分: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
答案 1 :(得分: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进行SandPRating
和MaturityBand
测试,因为当行包含累计计数时,NULL将替换其中一列或两列。
当然,这假定两个列{,1}都不能保存实际的NULL。省略汇总的更合适的方法可能是测试MaturityBand
的结果:如果它为两列返回GROUPING(column)
,请在总数中包含0
:
COUNT(*)