新栏最近7天的销售总额

时间:2018-07-18 13:54:29

标签: sql sql-server tsql

我有以下数据集:

enter image description here

我想创建一个新列来汇总最近7天的销售情况。因此查询结果应如下所示:

enter image description here

请帮助 谢谢!

5 个答案:

答案 0 :(得分:1)

在标准SQL中,您将使用窗口函数-假设您每天都有数据:

select t.*,
       sum(sales) over (partition by itemid order by date rows between 6 preceding and current row) as sales_7
from t;

答案 1 :(得分:1)

似乎您正在使用SQL Server,则可以使用apply

select t.*, t1.[last7day]
from table t outer apply
     (select sum(t1.sales) as [last7day]
      from table t1
      where t.itemid = t1.itemid  and 
            t1.date <= dateadd(day, -6, t.dt)
     ) t1;

答案 2 :(得分:0)

使用sum()聚合函数并按

分组
    select country,itemid,year,monthnumber,week sum(sales) as sales_last_7days  from your_table

    where date>=DATEADD(day, -7, getdate())  and date< getdate()

    group by country,itemid,year,monthnumber,week

答案 3 :(得分:0)

带窗口:

select (list other columns here), sum(sum(sales)) over 
    (partition by week
     order by day
     rows between 6 preceding and current row)
from table
group by date, week;

请注意,一周不会更改组,因为日期只推迟到一个星期,但是在窗口中需要。

答案 4 :(得分:0)

如果您 每一行都有一天,例如,如果您有交易清单...

下面的示例在我第一次看到它时就完全使我感到困惑,所以我尽了最大的努力来解释正在发生的事情。

假设我们有一个表tbl,其中有日期列dt和金额列amt,并且对于tbl中的每个日期,我们要返回金额的滚动总和从当日和过去6天开始。

select distinct  -- see note after code on what this distinct is doing.
    dt
    , ( -- Has to be in brackets to denote we're returning 1 value per row.
        -- for each row of T1:
        select sum(b.amt)  -- the sum of amounts in T2. The where clause will restrict which rows in T2 will be summed.
        from tbl T2
        where T2.dt between T1.dt - 6 and T1.dt  -- for each row in T1, give me all rows in T2 where the date is between 6 days before this T1 row's date and T1 row's date, giving us our rolling sum
        -- WARNING: CHECK YOUR VERSION OF SQL FOR HOW TO SUBTRACT DAYS FROM A DATE, I'VE MADE IT (T1.dt - 6) FOR SIMPLICITY
        -- we don't need a group by, because we're returning one value for each row in T1
    )
from tbl T1

我们有一个主版本tbl,别名为T1。然后,我们有了一个辅助表,别名为T2。对于T1中的每一行,我们将要求T2中的一组行,我们要在 之前求和到我们的主要查询中。

要了解正在发生的情况,请在不使用distinct的情况下运行代码。您会注意到,我们的行数与tbl中的行数相同,因为T2中的每一行都有T1语句。

注意:

  • 如果您的表中有几天没有任何行,您将无法获得这一天的计算结果。为确保不会发生这种情况,请将您的表加入到包含连续日期的不同列表的表中,并将其用作日期列。
  • 如果“金额”列中为空,则计算将仍然有效,但如果滚动平均值仅包含空值,则结果将为空而不是0。如果这样麻烦,请在使用查询之前(或之后)将所有null都转换为零。
  • 该期间的开始将“加速”。但是,无论您使用哪种方法进行总和,都将是相同的。如果您不满意,请不要返回前6天。

最后一个可行的示例,如果您正在使用SQL Server在家里玩的话:

with tbl as (
     -- a list of transactions from 1.10.2019 to 14.10.2019
    select cast('2019-10-01' as date) dt, 1 amt
    union select cast('2019-10-02' as date), 4
    union select cast('2019-10-01' as date), 10
    union select cast('2019-10-03' as date), 3
    union select cast('2019-10-04' as date), 20
    union select cast('2019-10-04' as date), 2
    union select cast('2019-10-04' as date), 12
    union select cast('2019-10-04' as date), 17
    union select cast('2019-10-05' as date), null -- a whole week of null values because we all had the week off... I hope this data wasn't important
    union select cast('2019-10-06' as date), null
    union select cast('2019-10-07' as date), null
    union select cast('2019-10-08' as date), null
    union select cast('2019-10-09' as date), null
    union select cast('2019-10-10' as date), null
    union select cast('2019-10-10' as date), null
    union select cast('2019-10-10' as date), null
    union select cast('2019-10-11' as date), null
    union select cast('2019-10-12' as date), 1
    union select cast('2019-10-12' as date), 1
    union select cast('2019-10-12' as date), 1
    union select cast('2019-10-12' as date), 1
    union select cast('2019-10-12' as date), 1
    union select cast('2019-10-12' as date), 1
    union select cast('2019-10-13' as date), 2
    union select cast('2019-10-14' as date), 1000
 )
select distinct
    a.dt
    , (
       select sum(b.amt)
       from tbl b
       where b.dt between dateadd(dd, -6, a.dt) and a.dt
   ) past_7_days_amt
from tbl a

返回:

+------------+-----------------+
|     dt     | past_7_days_amt |
+------------+-----------------+
| 2019-10-01 | 11              |
| 2019-10-02 | 15              |
| 2019-10-03 | 18              |
| 2019-10-04 | 69              |
| 2019-10-05 | 69              |
| 2019-10-06 | 69              |
| 2019-10-07 | 69              |
| 2019-10-08 | 58              |
| 2019-10-09 | 54              |
| 2019-10-10 | 51              |
| 2019-10-11 | NULL            |
| 2019-10-12 | 1               |
| 2019-10-13 | 3               |
| 2019-10-14 | 1003            |
+------------+-----------------+