【问题标题】:SQL - Sum of minutes between two timestamps by monthSQL - 每月两个时间戳之间的分钟总和
【发布时间】:2013-02-27 13:41:48
【问题描述】:

我正在寻找特定月份的开始日期和结束日期之间的分钟总和的 SQL 查询。

例如。 我正在查找 2 月份使用的分钟数。

开始日期时间:27-02-13 00:00:00 结束日期时间:05-03-13 00:00:00

因为我只在寻找 2 月的总和,所以它应该只给我 3 天的总和(以分钟为单位),而不是进入 3 月的额外 5 天。

【问题讨论】:

  • 哪些 RDBMS -- 日期/时间函数是特定于数据库的。
  • 我正在使用带有 sql 驱动程序的 odbc 连接到 SQL Server 2008 r2 机器。
  • 我尝试使用计算列并对数据求和,但是当数据流入下个月时,我的总和是错误的。

标签: sql sql-server-2008


【解决方案1】:

我无法验证它,但它应该看起来像:

SELECT DATEDIFF(minute, startDate, CASE when endDate > EOMONTH(startDate) THEN EOMONTH(startDate) ELSE endDate END) FROM ...

GL!

【讨论】:

  • 感谢 Eli,我没有 EOMONTH 函数,我将其替换为:SELECT DATEDIFF(minute, datetime5, CASE when datetime6 > dateadd(mm,datediff(mm,0,GetDate()))+ 1, 0) THEN dateadd(mm,datediff(mm,0,GetDate())+1, 0) ELSE datetime6 END)AS TotalMinutes,0 FROM AllUserData
  • 我现在唯一的挑战是,如果有人为上个月创建一个条目,其中包括本月的分钟数,我如何将它们包括在我的总和中。 :)
  • @Aaron 跟踪您处理的最后一个 ID 并处理除该 ID 之外的任何内容?不太确定你的总体目标是什么,所以这只是一个猜测。
【解决方案2】:

我将其分步说明每个过程。当然,您可以轻松地将其折叠起来,但我将由您来完成。

这是我的解决方案http://www.sqlfiddle.com/#!3/b4991/1/0

SELECT *
  , DATEDIFF(minute, StartDAte, NewEndDate) AS TotalMinutes
FROM
(
  SELECT *
    , CASE WHEN TempDate > EndDate THEN EndDate ELSE TempDate END AS NewEndDate -- Either EOM or old EndDate, whichever is smaller
  FROM
  (
    SELECT *
      , DATEADD(month, 1, CAST(Year + '-' + Month + '-1' AS DATETIME)) AS TempDate -- first day of the next month
    FROM
    (
      select *
       , CAST(DATEPART(month, StartDate) AS char(2)) AS Month
       , CAST(DATEPART(year, StartDate) AS char(4)) AS Year
      from tbl
    ) t0
  ) t1
) t2

首先我从原始StartDate 中得到年份和月份。然后我从中构建一个月初的日期。然后我加上一个月,让我得到下个月的第一个月。然后我检查新日期是 > 还是 EndDate。我取两个日期中较小的一个。然后我使用原始的StartDateTempDateEndDate 之间较小的那个来确定我的总分钟数。

另见 EOMONTH:http://msdn.microsoft.com/en-us/library/hh213020.aspx

【讨论】:

  • @Aaron 一旦您了解了我的回答所显示的基本内容,我会考虑使用stackoverflow.com/a/15113905/1795053 作为您的解决方案。它是一个大大简化/压缩的版本,使用内置的 SQL 函数来获取 EOMONTH 日期。
【解决方案3】:

考虑使用DATEDIFF -- 这只会帮助您入门:

SELECT DATEDIFF(minute, starttime, endtime) 

http://msdn.microsoft.com/en-us/library/ms189794.aspx

要获取开始月份的最后一天,请使用DATEADD

SELECT DATEADD(second,-1,DATEADD(month, DATEDIFF(month,0,starttime)+1,0))

SQL Fiddle Demo

【讨论】:

  • 我已经有 DATEDIFF 部分工作正常,我可以得到两列之间的差异。我挣扎的部分是如何按月分解。
  • @Aaron -- 你是否也想通过一个月然后在二月返回?或者您是否正在考虑从开​​始/结束时间对月份进行分组?
  • 是的,我也想通过一个月,然后二月回来。
  • @Aaron——我稍微编辑了我的答案——同样的逻辑应该在一个月内通过。 DATEADD 可以为您提供该月的最后一天,而 DATEDIFF 可以为您提供这些日期之间的时间差。祝你好运。
  • 不,请不要使用这个 dateadd(second,-1) 废话。
【解决方案4】:

我最近不得不解决一个类似的问题,我添加了两个新函数来帮助解决这个问题:

CREATE FUNCTION [dbo].[GREATESTDATE] 
(
    -- Add the parameters for the function here
    @Date1 DATETIME,
    @Date2 DATETIME
)
RETURNS DATETIME
AS
BEGIN


    IF (@Date1 < @Date2)
        RETURN @Date2
    ELSE 
        RETURN @Date1

END

还有……

CREATE FUNCTION [dbo].[LEASTDATE] 
(
    -- Add the parameters for the function here
    @Date1 DATETIME,
    @Date2 DATETIME
)
RETURNS DATETIME
AS
BEGIN

    IF (@Date1 > @Date2)
        RETURN @Date2
    ELSE 
        RETURN @Date1

END

然后像这样使用它们:

DATEDIFF(D,dbo.GREATESTDATE(@StartDate1,@StartDate2),dbo.LEASTDATE(@EndDate1,@EndDate2))

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-25
    相关资源
    最近更新 更多