正确的外部加入CTE问题

时间:2012-12-13 12:28:34

标签: sql-server tsql join common-table-expression outer-join

最终,我希望我的最终结果如下:

ReportingDate    FundCode    FundName    AssetClass    Rank    Percentage
-------------------------------------------------------------------------
30/11/2012       1           Fund1       Bond          1       50
30/11/2012       1           Fund1       Equity        2       30
30/11/2012       1           Fund1       Balanced      3       0
30/11/2012       1           Fund1       Other         4       20
30/11/2012       2           Fund2       Equity        1       60
30/11/2012       2           Fund2       Bond          2       20
.......    

基本上如果上面的例子中没有像Balanced那样的数据,我仍然希望在数据中返回这个,但百分比为0.

为了实现这一点,我在我的工作表中创建了一个名为@AssetClassRIGHT OUTER JOIN的表格,以便即使没有数据也可以返回所有AssetClass

我的脚本如下所示:

;;WITH CTE AS
(
SELECT 
        CASE 
            WHEN ReportingDate IS NULL THEN MAX(ReportingDate) OVER (PARTITION BY (SELECT 1)) 
            ELSE ReportingDate 
        END                     AS ReportingDate

    ,   CASE
            WHEN PortfolioID IS NULL THEN MAX(PortfolioID) OVER (PARTITION BY (SELECT 1)) 
            ELSE PortfolioID 
        END                     AS PortfolioID

    ,   CASE
            WHEN PortfolioNme IS NULL THEN MAX(PortfolioNme) OVER (PARTITION BY (SELECT 1)) 
            ELSE PortfolioNme 
        END                     AS PortfolioNme

    ,   AC.AssetClass           AS AssetClass

    ,   CASE
            WHEN AC.AssetClass = 'No Asset Class' THEN 3 
            WHEN AC.AssetClass = 'Other' THEN 2 
            ELSE 1
        END                     AS [Rank]
    ,   CAST(SUM(ISNULL(Percentage, 0)) AS DECIMAL(22,1))  AS [Weight]

FROM @Worktable as WT

    RIGHT OUTER JOIN @AssetClass AS AC
        ON RTRIM(WT.AssetClass) = RTRIM(AC.AssetClass)

GROUP BY WT.ReportingDate, WT.PortfolioID, WT.PortfolioNme, AC.AssetClass
)

SELECT 
        CONVERT(VARCHAR, ReportingDate, 103)    AS ReportingDate    
    ,   PortfolioID                             AS FundCode
    ,   PortfolioNme                            AS FundName
    ,   AssetClass
    ,   RANK() OVER (   PARTITION BY PortfolioID 
                        ORDER BY [Rank], [Weight] DESC) AS [Rank]
    ,   [Weight]                                AS Percentage
FROM CTE

ORDER BY ReportingDate, PortfolioID, [Rank], [Weight] DESC

我的问题是,当我为一个投资组合运行时,这非常有效。当我为多个组合运行它时,似乎在最终选择中排除了没有数据的任何东西,因此在上面的例子中,不返回Balanced行。

我的脚本是否存在问题,或者我是否正确加入@AssetClass?在我的剧本中是否有我遗漏的东西或我可以改进的东西?

1 个答案:

答案 0 :(得分:1)

可能这可以帮到你 更新03.01.2013

 ;WITH CTE AS
(
SELECT DISTINCT WT.ReportingDate, WT.PortfolioID, WT.PortfolioNme,        
       AC.AssetClass,
       CASE WHEN AC.AssetClass = 'No Asset Class' THEN 3 
            WHEN AC.AssetClass = 'Other' THEN 2 
            ELSE 1 END AS [Rank],        
       SUM(CASE WHEN AC.PortfolioID IS NULL THEN 0.00 ELSE WT.Percentage END)
       OVER(PARTITION BY WT.ReportingDate, WT.PortfolioID, AC.AssetClass) AS [Weight]
FROM Worktable WT CROSS APPLY (
                               SELECT AC2.AssetClass, WT2.ReportingDate, WT2.PortfolioID,
                                      WT2.AssetClass AS AssetClass2 
                               FROM AssetClass AC2 LEFT JOIN Worktable WT2 
                                 ON RTRIM(AC2.AssetClass) = RTRIM(WT2.AssetClass)
                                   AND WT2.PortfolioID = WT.PortfolioID                                                              
                               ) AC
WHERE (WT.ReportingDate = AC.ReportingDate AND WT.PortfolioID = AC.PortfolioID AND WT.AssetClass = AC.AssetClass)
        OR (AC.AssetClass2 IS NULL)
GROUP BY WT.ReportingDate, WT.PortfolioID, WT.PortfolioNme,          
         AC.AssetClass, AC.PortfolioID, WT.Percentage
)
SELECT CONVERT(VARCHAR, ReportingDate, 103) AS ReportingDate,
       PortfolioID AS FundCode,
       PortfolioNme AS FundName,
       AssetClass,
       RANK() OVER (PARTITION BY PortfolioID 
                    ORDER BY [Rank], [Weight] DESC) AS [Rank],
       [Weight] AS Percentage
FROM CTE
ORDER BY ReportingDate, PortfolioID, [Rank], [Weight] DESC