sql server - 计算总和计算达到某个值的日期

时间:2015-06-03 15:46:51

标签: sql sql-server date sum

我有一个活动表,如下所示:

activity_id         int
activity_client_id  int
activity_type_id    int
activity_start_date datetime
activity_end_date   datetime

执行活动的客户的每个实例的一条记录。 例如,今天他们可能有一个活动记录,其中包含activity_start_date of' 03-JUN-2015 09:00:00'和activity_end_date of' 03-JUN-2015 11:30:00'

因此,使用此表,我们可以通过这样做总计客户端执行的活动的分钟数:

select client_id,
sum(DATEDIFF(MINUTE, activity_start_date , activity_end_date)) as total_minutes
from activity
group by client_id

这里有点棘手:我需要运行一个查询,显示每个客户端达到总共300分钟活动的日期。

我正在考虑创建一个循环遍历每个客户端的存储过程,保持活动分钟的运行计数。当它达到300分钟时,该过程更新另一个表上的列,记录日期。

但是,我想知道我是否可以使用select查询动态获得结果而不必运行存储过程?

编辑:根据要求,我会给你一些样本数据,以澄清我想要实现的目标。 下面我们可以看到client_id 112的记录。 问题是,客户在什么日期完成了300分钟(5小时)的总活动? 对于这个客户,答案是03/06/2015

+-------------+----------------------+---------------------+-------------------+
| activity_id | activity_client_id   | activity_start_date | activity_end_date |
+-------------+----------------------+---------------------+-------------------+
|      112434 |                  112 | 01/06/2015 09:00    | 01/06/2015 11:00  |
|      112490 |                  112 | 02/06/2015 12:00    | 02/06/2015 16:00  |
|      112688 |                  112 | 03/06/2015 09:00    | 03/06/2015 16:00  |
|      112998 |                  112 | 04/06/2015 09:00    | 04/06/2015 10:00  |
+-------------+----------------------+---------------------+-------------------+

所以使用select语句,我们怎么能解决这个问题呢? 我可以使用循环来计算如何在存储过程中执行此操作,但我更希望只有一个select语句。

3 个答案:

答案 0 :(得分:1)

这个怎么样:

select client_id,
sum(DATEDIFF(MINUTE, activity_start_date , activity_end_date)) as total_minutes
from activity
group by client_id
having sum(DATEDIFF(MINUTE, activity_start_date , activity_end_date)) > 300

这将为您提供总活动时间> 300分钟的所有客户。将该列表发送到存储过程以进行更新。

答案 1 :(得分:1)

您需要的是累计金额。这最好在SQL Server 2012+中完成,但您可以在早期版本中实现它(效率较低):

select a.*
from (select a.*, a2.cume_minutes,
             (a2.cume_minutes - datediff(minute, a2.activity_start_date, 
                                         a2.activity_end_date)
                                        ) as prev_cume_minutes
      from activity a cross apply
           (select sum(datediff(minute, a2.activity_start_date, a2.activity_end_date)) as cume_minutes
            from activity a2
            where c2.client_id = a.client_id and
                  a2.activity_start_date <= a.activity_start_date
           ) a2
      ) a
where prev_cume_minutes < 300 and cum3_minutes >= 300;

这假设活动周期不重叠,这似乎是基于样本数据的情况。

答案 2 :(得分:0)

感谢您的所有输入,我没有清楚地解释这个场景,而且我已经过度简化了我的示例数据。 我发布了一个新问题,我希望能更好地解释这个: SQL Server - cumulative sum on overlapping data - getting date that sum reaches a given value