【问题标题】:Round time to half hour intervals and sum it将时间四舍五入到半小时间隔并求和
【发布时间】:2021-09-30 01:10:49
【问题描述】:

我将时间存储为 int,如下面的时间列所示。

我可以使用已定义的函数转换为日期时间或秒数,但我需要在舍入到 30 分钟后对其求和。

-----------------------------------------------------------------
Time       | datetime                | desired output as datetime
-----------------------------------------------------------------
11600      | 2021-05-05 01:16:00.000 |  2021-05-05 01:30:00.000
200        | 2021-05-19 00:02:00.000 |  2021-05-19 00:30:00.000
100        | 2021-05-10 00:01:00.000 |  2021-05-10 00:30:00.000
23000      | 2021-05-21 02:30:00.000 |  2021-05-21 02:30:00.000
-----------------------------------------------------------------

到目前为止,我管理的是将 int 转换为 datetime,然后在条件上舍入到 30 分钟(上面的所需输出列),但我仍然需要对其求和,不能这样:

;with t as(
SELECT 
[dbo].[sys_time_from_int](DATE,TIME_AWAY) DATE_AUX
FROM [time_sheet] x1
)
SELECT 
  CASE 
  WHEN datepart(MINUTE, DATE_AUX) = 30 or  datepart(MINUTE, DATE_AUX) = 00  
  THEN  DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( second, ( 30 * 60 ) / 2, DATE_AUX) ) / 30 ) * 30, 0 )
  ELSE  DATEADD( minute, ( DATEDIFF( minute, 0, DATEADD( minute,   30           , DATE_AUX) ) / 30 ) * 30, 0 )
 end as TIME_AUX
from t

看到的函数采用 (2021-05-05, 11600) 并将其转换为日期时间。 我也可以使用c#。 任何提示将不胜感激。

【问题讨论】:

  • 这能回答你的问题吗? How can I round up the time to the nearest X minutes? 它是 C# 但非常方便的扩展,因此您可以四舍五入到您想要的任何原子性。移植到 SQL 应该不是问题,因为这是严格的数学运算。
  • 我认为 C# 更容易;将其加载为时间跨度并将其处理为TimeSpan.FromMinutes(Math.Round(timespanfromdb.TotalMinutes/30)*30)

标签: c# sql-server datetime rounding


【解决方案1】:

看起来你正在积极四舍五入(因此是+29)。

也许这会有所帮助

示例

Declare @YourTable Table ([Time] int,[datetime] datetime)  
Insert Into @YourTable Values 
 (11600,'2021-05-05 01:16:00.000')
,(200,'2021-05-19 00:02:00.000')
,(100,'2021-05-10 00:01:00.000')
,(23000,'2021-05-21 02:30:00.000')
 
Select * 
      ,NewValue = dateadd(minute,((datediff(minute,0,[datetime])+29)  / 30) * 30,0)
 From @YourTable

结果

Time    datetime                    NewValue
11600   2021-05-05 01:16:00.000     2021-05-05 01:30:00.000
200     2021-05-19 00:02:00.000     2021-05-19 00:30:00.000
100     2021-05-10 00:01:00.000     2021-05-10 00:30:00.000
23000   2021-05-21 02:30:00.000     2021-05-21 02:30:00.000

使用聚合更新

 Select sum((datepart(hour,NewValue)*60) + datepart(minute,NewValue)) / 60.0
  From  @YourTable
  Cross Apply (values ( ( dateadd(minute,((datediff(minute,0,[datetime])+29)  / 30) * 30,0) ) ) ) b(NewValue)

【讨论】:

  • 这行得通,但问题是我需要对时间求和,所以在这个例子中我会有一行 5 作为输出
  • @TheOne__ 见用聚合更新
  • @TheOne__ 添加了另一个(更清洁)选项
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-26
  • 2018-06-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多