在当前行中,对代表上周(7 天)记录的行的数据求和

Posted

技术标签:

【中文标题】在当前行中,对代表上周(7 天)记录的行的数据求和【英文标题】:In the current row, sum the data for rows that represent records for last week (7 days) 【发布时间】:2020-07-16 09:19:08 【问题描述】:

我有 SQL 表 BaseDatavalue 列中的值是随机的):

------------------------------------------------------
|    Date    |    Value    |  Day  |  Moth  |  Year  |
------------------------------------------------------
| 01-07-2020 |      1      |   1   |    7   |  2020  |
| 02-07-2020 |      2      |   2   |    7   |  2020  |
| 03-07-2020 |      3      |   3   |    7   |  2020  |
| 04-07-2020 |      4      |   4   |    7   |  2020  |
| 05-07-2020 |      5      |   5   |    7   |  2020  |
| 06-07-2020 |      6      |   6   |    7   |  2020  |
| 07-07-2020 |      7      |   7   |    7   |  2020  |
| 08-07-2020 |      8      |   8   |    7   |  2020  |
| 09-07-2020 |      9      |   9   |    7   |  2020  |
| 10-07-2020 |      10     |   10  |    7   |  2020  |
------------------------------------------------------

我需要的是,从BaseData 查询数据,对于每一行,我将获得过去 7 天的ValuesSUM(不包括当天)。

例如,对于 7 月 8 日,我们应该得到 7 月 1 日到 7 月 7 日之间的值的总和。

例如,这应该是我上面给定示例的结果表:

----------------------------
|    Date    |  ResultSum  | 
----------------------------
| 01-07-2020 |      0      | //assuming this is the first record
| 02-07-2020 |      1      | //SUM = 1
| 03-07-2020 |      3      | //SUM = 1 + 2
| 04-07-2020 |      6      | //SUM = 1 + 2 + 3
| 05-07-2020 |      10     | //SUM = 1 + 2 + 3 + 4
| 06-07-2020 |      15     | //SUM = 1 + 2 + 3 + 4 + 5
| 07-07-2020 |      21     | //SUM = 1 + 2 + 3 + 4 + 5 + 6
| 08-07-2020 |      28     | //SUM = 1 + 2 + 3 + 4 + 5 + 6 + 7
| 09-07-2020 |      35     | //SUM = 2 + 3 + 4 + 5 + 6 + 7 + 8
| 10-07-2020 |      42     | //SUM = 3 + 4 + 5 + 6 + 7 + 8 + 9
----------------------------

到目前为止我所拥有的是:

SELECT Date,
       (SELECT SUM(nestedTable.Value)
        FROM BaseData AS nestedTable
        WHERE DATEADD(dd, DATEDIFF(dd, 0, Date), 0) BETWEEN
              DATEADD(day, DATEDIFF(day, 0, DATEADD(d,-1, Date)), 0) AND
              DATEADD(day, DATEDIFF(day, 0, DATEADD(d,-8, Date)), 0)
       ) AS ResultSum
FROM BaseData

但似乎它不起作用。我发现了一些类似的问题here,但我无法弄清楚如何在这里使用这些答案。

【问题讨论】:

升级到受支持的 SQL Server 版本,这很简单,因为您可以访问 OVER 子句中的 ROWS BETWEEN。考虑到 SQL Server 2008 已经完全不受支持一年了,您应该也已经有了这些升级计划。 请edit 与proper sample data 联系您的问题。 @ZoharPeled 表格格式的文本“很好”,因为它至少可以轻松消费。它比我们经常看到的图像要好得多。 @Larnu 我不会把我的标准降低这么多,说它“很好”。充其量可以说是半体面,但你是对的,我也觉得最近的问题质量正在下降(顺便说一句,投票按钮上的简单手也是如此。我投票得最好的答案是一个相当新的答案只不过是一个文档引用 - 我写了更好的答案,不幸的是得到了 0 分......) @delux sqlfiddle 有一个漂亮的小按钮,叫做“Text to DDL”。试一试。 【参考方案1】:

只需使用窗口函数。假设日期在表中是连续的,你会这样做:

select
    date,
    coalesce(
        sum(value) over(order by date rows between 7 preceding and 1 preceding),
        0
    ) resultsum
from basedata

在不支持窗口函数的rows 子句的 SQL Server 版本中,您可以改用相关子查询或横向连接:

select
    date,
    (
        select coalesce(sum(b1.value), 0)
        from basedata b1
        where b1.date between dateadd(day, -7, b.date) and dateadd(day, -1, b.date)
    ) resultsum
from basedata b

此查询将利用date 列上的索引 - 它具有处理非连续日期的优势。

这两个查询都假定日期存储为数据类型 date(或类似的) - 如果不是这种情况,您需要先 cast() 它们(或者更好......修复您的数据模型!)。

【讨论】:

不幸的是,OP 标记了 SQL Server 2008。ROWS BETWEEN 仅在 SQL Server 的受支持版本中可用,因为它是随 SQL Server 2012 引入的。 假设日期在表格中是连续的...... @Larnu:啊,是的,一开始没有发现。而是使用相关子查询来回答更新。 @ZoharPeled:确实 - OP 的样本数据并未以其他方式显示。 没错,@GMB,但你确实(讽刺地)在三角连接中处理了这个逻辑。 :)

以上是关于在当前行中,对代表上周(7 天)记录的行的数据求和的主要内容,如果未能解决你的问题,请参考以下文章

如何在所有行中按顺序更新组号

提取上周数据(而不是过去7天)

在当前选定的行中自动打开超链接

加入求和时限制 SQL 中返回的行的最佳方法

Apache Beam 根据前一行的值更新当前行的值

对 data.frame 或矩阵中的行求和