过去n周的sql销售额总和,包括销售额为0的一周

d6kp6zgx  于 2021-08-09  发布在  Java
关注(0)|答案(4)|浏览(540)

我想显示每件商品每周(本周加上前3周)4周销售额的总和。
原始数据

  1. +--------+--------+----------+
  2. | Item | Week | sales |
  3. +--------+--------+----------+
  4. | a | 1 | 10 |
  5. | a | 2 | 10 |
  6. | a | 4 | 10 |
  7. | a | 7 | 10 |
  8. | a | 8 | 10 |
  9. | a | 10 | 10 |
  10. | b | 1 | 10 |
  11. | b | 2 | 10 |
  12. | b | 4 | 10 |
  13. | b | 7 | 10 |
  14. | b | 8 | 10 |
  15. | b | 10 | 10 |
  16. +--------+--------+----------+

预期结果(以a项为例)

  1. +------+------+------------------------------------------------------+
  2. | Item | Week | sales |
  3. +------+------+------------------------------------------------------+
  4. | a | 1 | 10 |
  5. | a | 2 | 20 |
  6. | a | 3 | 30 |
  7. | a | 4 | 30 |
  8. | a | 5 | 20(Note: sales of Week 5+Week 4+Week 3+Week 2) |
  9. | a | 6 | 10 |
  10. | a | 7 | 20[Note: 10(Week 7)+0(Week 6)+0(Week 5)+10 (Week 4)] |
  11. | a | 8 | 20 |
  12. | a | 9 | 20 |
  13. | a | 10 | 30(Note: sales of Week 10+Week 9+Week 8+Week 7) |
  14. +------+------+------------------------------------------------------+

我试着用

  1. sum (sales) over (partition by item order by week row 3 preceding)

然而,它跳过了没有销售记录的一周,把所有的非零值加起来。例如:对于第7周,sum over将第7、4、2、1周的销售额相加,计算结果为40。有没有办法达到预期的效果?

34gzjxbg

34gzjxbg1#

  1. SELECT week,Item ,sum(sales) WHERE (curweek - week < 4) group by week,Item
cedebl8k

cedebl8k2#

每周,如果你的table是table

  1. SELECT sum(B.sales), A.week as curweek As totalsales
  2. FROM table A, table B
  3. WHERE curweek - B.week <4
  4. AND curweek - B.week >=0
  5. GROUP BY curweek
egmofgnx

egmofgnx3#

由于问题没有提到rdbms,我在sql server中测试了下面的代码。下面的解决方案是针对sql server的
我正在做以下活动:
生成周、项的所有组合
对于组合,生成前4周的总和(销售额)
删除原始列表中不存在的周

  1. DECLARE @table TABLE (Item CHAR(1), Week TINYINT, sales INT)
  2. INSERT INTO @table
  3. VALUES ('a', 1, 10), ('a', 2, 10), ('a', 4, 10), ('a', 7, 10), ('a', 8, 10), ('a', 10, 10), ('b', 1, 10), ('b', 2, 10), ('b', 4, 10), ('b', 7, 10), ('b', 8, 10), ('b', 10, 10);;
  4. WITH CTE_ItemWeek
  5. AS (
  6. SELECT Item, Week
  7. FROM (
  8. VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10)
  9. ) AS t(week)
  10. CROSS JOIN (
  11. SELECT DISTINCT Item
  12. FROM @table
  13. ) A
  14. )
  15. SELECT *
  16. FROM (
  17. SELECT t1.Item, CASE
  18. WHEN t2.Week IS NULL
  19. THEN LAG(t2.week) OVER (
  20. PARTITION BY t1.Item ORDER BY t2.week
  21. )
  22. ELSE t2.week
  23. END AS week, SUM(t2.sales) OVER (
  24. PARTITION BY t1.Item ORDER BY t1.week ROWS BETWEEN 3 preceding
  25. AND CURRENT ROW
  26. ) AS total_sales
  27. FROM CTE_ItemWeek AS t1
  28. LEFT OUTER JOIN @table AS t2 ON t1.Item = t2.Item
  29. AND t1.week = t2.week
  30. ) AS t
  31. WHERE week IS NOT NULL

结果集

  1. +------+------+-------------+
  2. | Item | week | total_sales |
  3. +------+------+-------------+
  4. | a | 1 | 10 |
  5. | a | 2 | 20 |
  6. | a | 4 | 30 |
  7. | a | 7 | 20 |
  8. | a | 8 | 20 |
  9. | a | 10 | 30 |
  10. | b | 1 | 10 |
  11. | b | 2 | 20 |
  12. | b | 4 | 30 |
  13. | b | 7 | 20 |
  14. | b | 8 | 20 |
  15. | b | 10 | 30 |
  16. +------+------+-------------+
展开查看全部
7uzetpgm

7uzetpgm4#

如果您只需要查看现有周数的总和(因此不必填充缺少的周数),可以在标准sql中使用范围而不是行来实现这一点:

  1. select item,
  2. week,
  3. sum (sales) over (partition by item order by week range between 3 preceding and current row)
  4. from the_table
  5. order by item, week;

如果您需要以行的形式填写缺少的周,那么答案在很大程度上取决于所使用的dbms。在postgres中,您可以执行以下操作:

  1. with items as (
  2. select distinct item
  3. from data
  4. ), all_weeks as (
  5. select i.item, g.week
  6. from items i
  7. cross join generate_series(1,10) as g(week)
  8. )
  9. select t.item,
  10. t.week,
  11. sum (d.sales) over (partition by t.item order by t.week range between 3 preceding and current row)
  12. from all_weeks t
  13. left join data d on d.item = t.item and d.week = t.week

对于其他dbms系统 generate_series() 呼叫可以替换为固定的周数:

  1. select i.item, g.week
  2. from items i
  3. cross join ( values (1),(2),(3),(4),(5),(6),(7),(8),(9),(10) ) as g(week)

在线示例

展开查看全部

相关问题