【问题标题】:Right Outer Join Issue in a CTECTE 中的右外连接问题
【发布时间】:2012-12-13 12:28:33
【问题描述】:

最终我希望我的最终结果如下所示:

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?我的脚本中有什么遗漏或可以改进的地方吗?

【问题讨论】:

  • 可以给@Worktable表数据吗?

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


【解决方案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   

【讨论】:

  • 抱歉这么晚才回复。由于圣诞节和新年而休假。在“@AssetClass”表中,我只有其中的资产类别列表,因此您上面建议的方式将不起作用。当“@AssetClass”表中没有资产类别的数据时,我需要执行 PARTITION BY 以便在 Reporting Date、PortfolioID 和 PortfolioNme 中填充数据。
  • 工作完美,虽然有点慢,但至少你给了我一些工作。非常感谢。
猜你喜欢
  • 2012-11-07
  • 1970-01-01
  • 2012-02-26
  • 1970-01-01
  • 1970-01-01
  • 2021-10-12
  • 1970-01-01
  • 2014-02-24
  • 1970-01-01
相关资源
最近更新 更多