tsql - 我可以在CASE语句中执行此操作吗?

时间:2013-08-28 13:36:54

标签: sql-server-2008 tsql case common-table-expression

我有两个结果集,如下所示:

@Rounding

PortfolioID Duration
AAA     -0.1

@FinalOutput

ReportingDate   FundCode    Sector      Rank    Duration    Weight
31/07/2013      AAA         Sector1     1       0           33.5
31/07/2013      AAA         Sector2     2       0.9         29.6
31/07/2013      AAA         Sector3     3       0.6         17.3
31/07/2013      AAA         Sector4     4       0.8         11.8
31/07/2013      AAA         Sector5     5       0.1         3.1
31/07/2013      AAA         Sector6     6       0.1         1.3
31/07/2013      AAA         Sector7     7       0           0.4
31/07/2013      AAA         Sector8     8       -0.9        0
31/07/2013      AAA         Sector9     11      0           -1.3
31/07/2013      AAA         Sector10    100     0           2.8
31/07/2013      AAA         Sector11    101     0           1.5
31/07/2013      AAA         Total       102     1.6         100

我需要做的是从等级1和等级102持续时间中减去@Rounding中的持续时间,但是如果等级1是“Sector1”,那么我需要从等级2中减去它。这是否可能在一个案例陈述?我已经创建了以下内容,但我不知道如何处理“Sector1”的情况,如果它是1级则永远不会被减去?

    SELECT 
        ReportingDate
    ,   FundCode
    ,   Sector
    ,   [Rank]

    ,   CASE
            WHEN [Rank] IN (1,102) THEN [Duration Contribution] - RD1.Duration
            ELSE [Duration Contribution]

        END     AS [Duration Contribution]

    ,   CASE 
            WHEN [Rank] IN (1,102) THEN Percentage - RD.[Weight]
            ELSE Percentage

        END     AS Percentage

    FROM CTE AS CTE

        INNER JOIN @RoundingDifference AS RD  -- Portfolio Weight Rounding
            ON RD.PortfolioID = CTE.FundCode

        INNER JOIN @RoundingDifferenceDur AS RD1 -- Duration Contribution Rounding
            ON RD1.PortfolioID = CTE.FundCode

    WHERE (Percentage <> 0.0
    OR [Duration Contribution] <> 0.0)

    ORDER BY    ReportingDate
            ,   FundCode
            ,   [Rank]

所以我要找的结果是Sector 1 Duration仍然= 0但Sector 2 Duration和Total分别为1.0和1.7。

1 个答案:

答案 0 :(得分:0)

sql在处理集合中的行N时是否真的不知道它是否在行N-1中找到特定值。这意味着只有当Rank 1记录具有某个特定的Sector值时,你才能真正告诉它对Rank 2记录做一些特殊的事情。

但是,您可以使用子查询来检查该集合是否具有Rank 1的行并且还具有Sector1。

您需要使用详细的案例陈述来执行此操作,如果数据集很大,性能可能会很差。

select
    case
        when Rank = 102
            then [Duration Contribution] - RD1.Duration
        when Rank = 1 and Sector != 'Sector1'
            then [Duration Contribution] - RD1.Duration
        when Rank = 2 and exists (select * from cte where Rank = 1 and Sector = 'Sector1')
            then [Duration Contribution - RD1.Duration
        else [Duration Contribution]
    end