繁体   English   中英

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

[英]sql get previous row value for a running total

我有一个查询,已经在为新客户端和已离开的客户端计算运行总计。 但是,如果在尝试将其绘制在图形上时没有新客户或没有客户离开,则会出现空格。

如果一年为空,如何获得前几年的数字?

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

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

这是我的修改代码,我在select中更改了2行以使用lag函数,并在答案中使用了链接以使其正常工作。

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

如果使用的是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也是一种比使用group by join来获取累计总和的更好方法。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM