【问题标题】:SQL Counting Total Time but resetting total if large gapSQL 计算总时间,但如果差距较大则重置总时间
【发布时间】:2011-09-29 02:43:50
【问题描述】:

我有一个包含设备移动的表格。

MoveID DeviceID Start End

我想知道是否有办法总结每个设备到现在的总移动天数。但是,如果结束日期和下一个开始日期之间有 6 周的间隔,则时间计数会被重置。

MoveID    DeviceID    Start     End
1           1         2011-1-1  2011-2-1
2           1         2011-9-1  2011-9-20
3           1         2011-9-25 2011-9-28

设备的总天数应为 24 天,因为间隔大于 6 周。另外我想找出自组中第一次移动以来的天数,在这种情况下为 28 天,因为最新的计数组于 2011-9-1 开始

我认为我可以使用存储过程和游标等(这不好)来完成它,只是想知道是否有更好的方法?

谢谢

格雷姆

【问题讨论】:

    标签: sql sql-server tsql sql-server-2008


    【解决方案1】:
    create table #test
    (
    MoveID int,
    DeviceID int,
    Start date,
    End_time date
    )
    --drop table #test
    insert into #test values
    (1,1,'2011-1-1','2011-2-1'),
    (2,1,'2011-9-1','2011-9-20'),
    (3,1,'2011-9-25','2011-9-28')
    
    select 
       a.DeviceID, 
       sum(case when datediff(dd, a.End_time, isnull(b.Start, a.end_time)) > 42 /*6 weeks = 42 days*/ then 0 else datediff(dd,a.Start, a.End_time)+1 /*we will count also the last day*/ end) as movement_days,
    

    sum(case when datediff(dd, a.End_time, isnull(b.Start, a.end_time)) > 42 /6 周 = 42 天/ then 0 else datediff(dd,a .Start, a.End_time)+1 /我们也会计算最后一天/ end + case 当 b.MoveID 为空时 datediff(dd, a.Start, a.End_time) + 1 else 0 结束)作为 total_days
    从 #测试一个 左连接#test b a.DeviceID = b.DeviceID 和 a.MoveID + 1 = b.MoveID 通过...分组 a.设备ID

    如果您需要一些解释,请告诉我 - 可以有更多方法来做到这一点...

    【讨论】:

    • 据我所知,这非常适合获得总天数:)。无论如何要获取每个设备当前期间第一个日期以来的天数?
    • 这看起来好像依赖于 MoveID 在每个 DeviceID 中是连续的。是这样吗?
    • 应该是,但我不想依赖它。用户可能已经返回并更改了日期等。
    • 我还添加了 28 天计算
    • 非常感谢您的回答和帮助。你是第一个所以也许应该接受你的答案。不确定接受答案的礼仪似乎不在常见问题解答中。
    【解决方案2】:
    DECLARE @Times TABLE
    (
        MoveID INT,
        DeviceID INT,
        Start DATETIME,
        [End] DATETIME
    )
    
    INSERT INTO @Times VALUES (1, 1, '1/1/2011', '2/1/2011')
    INSERT INTO @Times VALUES (2, 1, '9/1/2011', '9/20/2011')
    INSERT INTO @Times VALUES (3, 1, '9/25/2011', '9/28/2011')
    
    INSERT INTO @Times VALUES (4, 2, '1/1/2011', '2/1/2011')
    INSERT INTO @Times VALUES (5, 2, '3/1/2011', '4/20/2011')
    INSERT INTO @Times VALUES (6, 2, '5/1/2011', '6/20/2011')
    
    DECLARE @MaxGapInWeeks INT
    SET @MaxGapInWeeks = 6
    
    SELECT
        validTimes.DeviceID,
        SUM(DATEDIFF(DAY, validTimes.Start, validTimes.[End]) + 1) AS TotalDays,
        DATEDIFF(DAY, MIN(validTimes.Start), MAX(validTimes.[End])) + 1 AS TotalDaysInGroup
    FROM 
        @Times validTimes LEFT JOIN
        @Times timeGap 
            ON timeGap.DeviceID = validTimes.DeviceID
            AND timeGap.MoveID <> validTimes.MoveID
            AND DATEDIFF(WEEK, validTimes.[End], timeGap.Start) > @MaxGapInWeeks
    WHERE timeGap.MoveID IS NULL
    GROUP BY validTimes.DeviceID
    

    【讨论】:

    • 只是想知道如何获取自期间列开始以来的总天数。例如。对于 DeviceID 1,它应该是 28 天。自 2011 年 9 月 1 日新时期开始
    • 啊,抱歉,我错过了最后一部分...我已经更新了脚本以包含它。
    • 我接受你的回答。 MaxGapInWeeks 变量的灵活性,使用我的示例结束列名称和附加测试答案,并使用表变量而不是临时表。非常感谢您的帮助。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多