sql获取正在运行的总计的上一行值

时间:2015-02-04 11:01:53

标签: sql sql-server

我有一个查询已经为剩下的新客户和客户计算了一个运行总计。但是,当我尝试在图表上绘制时,如果没有新客户或没有客户离开,我会得到空格。

如果一年为空,我怎样才能获得前几年的数据?

select x.Year
        , case when x.TotalClients is null then 0 else x.TotalClients end as 'TotalNewClients'
        , x.RunningTotal as 'RunningTotalNewClients'
        , case when x2.TotalClients is null then 0 else x2.TotalClients end as 'TotalLeftClients'
        , x2.RunningTotal as  'RunningTotalLeftClients'
from (
        SELECT
            st1.YearStart as 'Year',
            st1.TotalClients,
            RunningTotal = SUM(st2.TotalClients)
        FROM
            @TotalsStart AS st1
        INNER JOIN
            @TotalsStart AS st2
            ON st2.YearStart <= st1.YearStart
        GROUP BY st1.YearStart, st1.TotalClients) as x
left outer join 
        (SELECT
            st1.YearStart  as 'Year',
            st1.TotalClients,
            RunningTotal = SUM(st2.TotalClients)
        FROM
            @TotalsEnd AS st1
        INNER JOIN
            @TotalsEnd AS st2
            ON st2.YearStart <= st1.YearStart
        GROUP BY st1.YearStart, st1.TotalClients
        ) as x2 on x.Year = x2.Year
Order by x.Year

3 个答案:

答案 0 :(得分:0)

也许滞后功能(msdn.microsoft.com/en-us/library/hh231256.aspx)可以帮到你吗?

答案 1 :(得分:0)

这是我的修改后的代码,我在select中更改了2行以使用滞后函数,我在回答中使用了链接来使其工作。

select x.Year
        , case when x.TotalClients is null then 0 else x.TotalClients end as 'TotalNewClients'
        , x.RunningTotal 
        , case when x.RunningTotal is null then lag(x.RunningTotal,1,0) over(order by x.year) else x.RunningTotal end as  'RunningTotalNewClients'
        , case when x2.TotalClients is null then 0 else x2.TotalClients end as 'TotalLeftClients'
        , x2.RunningTotal
        , case when x2.RunningTotal is null then lag(x2.RunningTotal,1,0) over(order by x.year) else x2.RunningTotal end as  'RunningTotalLeftClients'
from (
        SELECT
            st1.YearStart as 'Year',
            st1.TotalClients,
            RunningTotal = SUM(st2.TotalClients)
        FROM
            @TotalsStart AS st1
        INNER JOIN
            @TotalsStart AS st2
            ON st2.YearStart <= st1.YearStart
        GROUP BY st1.YearStart, st1.TotalClients) as x
left outer join 
        (SELECT
            st1.YearStart  as 'Year',
            st1.TotalClients,
            RunningTotal = SUM(st2.TotalClients)
        FROM
            @TotalsEnd AS st1
        INNER JOIN
            @TotalsEnd AS st2
            ON st2.YearStart <= st1.YearStart
        GROUP BY st1.YearStart, st1.TotalClients
        ) as x2 on x.Year = x2.Year
Order by x.Year

答案 2 :(得分:0)

如果您使用的是SQL Server 2012+,那么您的查询会变得复杂。只需使用累积和功能:

select coalesce(x.Year, x2.year) as year,
       coalesce(x.TotalClients, 0 ) as TotalNewClients,
       x.RunningTotal as RunningTotalNewClients
       coalesce(x2.TotalClients, 0) as TotalLeftClients,
       x2.RunningTotal as RunningTotalLeftClients
from (SELECT st.YearStart as Year, st.TotalClients,
             SUM(st.TotalClients) over (order by year) as RunningTotal
      FROM @TotalsStart st
     ) x full outer join 
     (SELECT st.YearStart  as Year, st.TotalClients,
             SUM(st.TotalClients) over (order by year) as RunningTotal
      FROM @TotalsEnd AS st
    ) x2
    on x.Year = x2.Year
Order by coalesce(x.Year, x2.year);

即使在早期版本的SQL Server中,apply也是使用join获取累计总和超过group by的更好方法。

顺便说一句,您应该仅对字符串和日期常量使用单引号,而不是列别名。虽然在这种情况下允许,但它们通常会导致查询中的混淆和难以发现的错误。