【问题标题】:Averaging event start time from DateTime columnDateTime 列的平均事件开始时间
【发布时间】:2018-06-28 02:31:14
【问题描述】:

我正在计算深夜运行且可能要到第二天早上才开始的活动的平均开始时间。

2018-01-09 00:01:38.000
2018-01-09 23:43:22.000

目前我只能生产平均 11:52:30.0000000

我希望结果是 ~ 23:52

平均时间不会保持不变,因为此事件每天都在运行,我每天都会有新数据。我可能会取最近的 10 条记录并取平均值。

【问题讨论】:

标签: sql tsql datetime average


【解决方案1】:

如果您正在运行 SQL 会很好,但您可能只需要正确格式化您的输出,它应该是这样的:

FORMAT(cast(<your column> as time), N'hh\:mm(24h)')

【讨论】:

    【解决方案2】:

    以下内容将计算日期时间字段的平均值,并将结果仅作为 24 小时时间表示法返回。

    SELECT CAST(CAST(AVG(CAST(<YourDateTimeField_Here> AS FLOAT)) AS DATETIME) AS TIME) [AvgTime] FROM <YourTableContaining_DateTime>
    

    【讨论】:

    • 我已经尝试过这个解决方案,但我仍然得到上午 11:52 而不是下午 23:52
    • 您确定正确答案不是 11:52?如果您愿意,当然可以在时间戳中添加 12 小时。
    • 是的,我确定...该过程在晚上而不是在白天运行(我提供的时间是晚上 11:52 和凌晨 12:01),增加 12 小时是行不通的,因为其他过程的平均值应该用相同的代码计算。
    【解决方案3】:

    以下将计算一天中的平均时间,无论那是哪一天。

    --SAMPLE DATA
    create table #tmp_sec_dif
        (
            sample_date_time datetime
        )
    
    insert into #tmp_sec_dif
    values ('2018-01-09 00:01:38.000')
        , ('2018-01-09 23:43:22.000')
    
    --ANSWER
    declare @avg_sec_dif int
    
    set @avg_sec_dif = 
        (select avg(a.sec_dif) as avg_sec_dif
        from (
            --put the value in terms of seconds away from 00:00:00
            --where 23:59:00 would be -60 and 00:01:00 would be 60
            select iif(
                datepart(hh, sample_date_time) < 12 --is it morning?
                , datediff(s, '00:00:00', cast(sample_date_time as time)) --if morning
                , datediff(s, '00:00:00', cast(sample_date_time as time)) - 86400 --if evening
                ) as sec_dif
            from #tmp_sec_dif
            ) as a
        )
    
    select cast(dateadd(s, @avg_sec_dif, '00:00:00') as time) as avg_time_of_day
    

    输出将是23:52:30.0000000的答案

    【讨论】:

    • 不幸的是,如果进程在 11:00 和 13:00 运行,则平均值并非在所有情况下都是 00:00,而不是 12:00
    • @KKohls 根据问题和 cmets 的其他答案,该过程似乎只在晚上运行,并且需要能够根据 12:00 - 11:59 24 找到平均时间小时时钟(而不是 00:00 - 23:59)。如果不是这样,您介意详细说明情况并添加相关示例数据以帮助进一步证明问题吗?
    【解决方案4】:

    此代码允许您定义日期分割点。例如18 确定下午 6 点。时间计算将基于下午 6 点后的秒数。

    -- Defines the hour of the day when a new day starts
    DECLARE @DayDivision INT = 18
    
    IF OBJECT_ID(N'tempdb..#StartTimes') IS NOT NULL DROP TABLE #StartTimes
    
    CREATE TABLE #StartTimes(
        start DATETIME NOT NULL
    )
    
    INSERT INTO #StartTimes
    VALUES 
         ('2018-01-09 00:01:38.000')
        ,('2018-01-09 23:43:22.000')
    
    SELECT 
        -- 3. Add the number of seconds to a day starting at the 
        --    day division hour, then extract the time portion
        CAST(DATEADD(SECOND,
            -- 2. Average number of seconds
            AVG(
                -- 1. Get the number of seconds from the day division point (@DayDivision)
                DATEDIFF(SECOND, 
                    CASE WHEN DATEPART(HOUR,start) < @DayDivision THEN
                        SMALLDATETIMEFROMPARTS(YEAR(DATEADD(DAY,-1,start)),MONTH(DATEADD(DAY,-1,start)),DAY(DATEADD(DAY,-1,start)),@DayDivision,0)
                    ELSE
                        SMALLDATETIMEFROMPARTS(YEAR(start),MONTH(start),DAY(start),@DayDivision,0)
                    END
                ,start)
            )
        ,'01 jan 1900 ' + CAST(@DayDivision AS VARCHAR(2)) + ':00') AS TIME) AS AverageStartTime
    FROM #StartTimes
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-10
      • 2011-01-14
      • 2012-09-21
      • 1970-01-01
      • 2014-01-26
      • 1970-01-01
      相关资源
      最近更新 更多