计算多行SQL Server

时间:2013-05-20 15:26:06

标签: sql sql-server tsql sql-server-2008-r2

如果我有格式的数据;

Account  | Period     | Values
Revenue  | 2013-01-01 | 5432
Revenue  | 2013-02-01 | 6471
Revenue  | 2013-03-01 | 7231
Costs    | 2013-01-01 | 4321
Costs    | 2013-02-01 | 5672
Costs    | 2013-03-01 | 4562

我想得到的结果就像;

Account  | Period     | Values
Margin   | 2013-01-01 | 1111
Margin   | 2013-02-01 |  799
Margin   | 2013-03-01 | 2669
M%       | 2013-01-01 |  .20
M%       | 2013-02-01 |  .13
M%       | 2013-03-01 |  .37

保证金=收入 - 成本和M%是(收入 - 成本)/每个期间的收入。

我可以看到实现这一目标的各种方法,但都非常难看,我想知道这些多行计算是否有优雅的通用方法。

由于

修改

其中一些计算可能会变得非常复杂,如

自由现金流=保证金 - Opex - 资本支出+营运资金变动+支付利息

所以我希望一个通用的方法不需要很多连接回自身。

由于

4 个答案:

答案 0 :(得分:1)

使用联盟的完全自我加入

Select 'Margin' Account, 
   coalesce(r.period, c.period) Period,
   r.Values - c.Values Values
From myTable r
   Full Join Mytable c
      On c.period = r.period
Union
Select 'M%' Account, 
   coalesce(r.period, c.period) Period,
   (r.Values - c.Values) / r.Values Values
From myTable r
   Full Join Mytable c
      On c.period = r.period

答案 1 :(得分:1)

在这里,我使用公用表表达式在数据表的两个实例之间进行完全外连接,以将收入和成本拉入1表,然后从该CTE中选择。

with RevAndCost as (revenue,costs,period)
as
(
    select  ISNULL(rev.Values,0) as revenue, 
            ISNULL(cost.values,0) as costs, 
        ISNULL(rev.period,cost.period)
    from data rev full outer join data cost
    on rev.period=cost.period
)

select Margin = revenue-costs,
   "M%" = (revenue-costs)/nullif(revenue,0)
from RevAndCost

答案 2 :(得分:1)

我会这样做:

SELECT r.PERIOD, r.VALUES AS revenue, c.VALUES AS cost,
r.VALUES - c.VALUES AS margin, (r.VALUES - c.VALUES) / r.VALUES AS mPct
FROM 
    (SELECT PERIOD, VALUES FROM t WHERE
    ACCOUNT = 'revenue') r INNER JOIN
    (SELECT PERIOD, VALUES FROM t WHERE
    ACCOUNT = 'costs') c ON
    r.PERIOD = c.PERIOD

答案 3 :(得分:1)

好的,然后只是Max over Case语句,就像这样:

with RevAndCost as (revenue,costs,period)
as
(

    select "Revenue" = Max(Case when account="Revenue" then Values else null end),
           "Costs" = MAX(Case when account="Costs" then values else null end),
           period
            from data
    group by period

)

select Margin = revenue-costs,
       "M%" = (revenue-costs)/nullif(revenue,0)
from RevAndCost