按日期和小时连续最多time_periods

时间:2014-07-25 18:01:28

标签: sql-server

对于特定练习,我需要找到并找到最大连续/连续日期和时间范围。 time_period以YYYY_MM_DD_hr HH格式给出,我转换为YYYY-MM-DD-HH:00:00:000以启用加法和减法运算。该数据是从2014年至2014年的预测,我相信我需要基本上标记'连续期间的开始和结束,即。 2014-01-01-01:00:00:000至2014-01-02:00:00:000将返回值' 1'。我正在使用Microsoft SQL Server Management Studio 2012.

到目前为止,我有类似的内容:

SELECT  r1.Report_Day ,
        r1.Report_Hour ,
        r1.report_month ,
        r1.report_year ,
        DATEADD(HOUR, r1.report_hour, CAST(CAST(r1.report_year AS VARCHAR) + '-' + CAST(r1.report_month AS VARCHAR) + '-' + CAST(r1.report_day AS VARCHAR) AS DATETIME)) AS 'NEWDATETIME'

3 个答案:

答案 0 :(得分:0)

要求不是很清楚,但似乎这方面的内容可行:

select newdatetime, newdatetime -(select max(newdatetime) 
from yourtable b where b.newdatetime<a.newdatetime) As Period
from yourtable a
order by newdatetime

答案 1 :(得分:0)

确定。假设您创建了NEWDATETIME列并且具有问题中提到的完整日期时间值,请尝试以下操作:

SELECT CONVERT(float, r1_1.NEWDATETIME - MAX(r1_2.NEWDATETIME)) * 24
FROM r1 r1_1
INNER JOIN r1 r1_2 ON r1_2.NEWDATETIME < r1_1.NEWDATETIME
GROUP BY r1_1.NEWDATETIME

这为您提供了小时数的所有差异。要找到所有的最大值:

SELECT MAX(hoursDiff) FROM (
SELECT CONVERT(float, r1_1.NEWDATETIME - MAX(r1_2.NEWDATETIME)) * 24 hoursDiff
FROM r1 r1_1
INNER JOIN r1 r1_2 ON r1_2.NEWDATETIME < r1_1.NEWDATETIME
GROUP BY r1_1.NEWDATETIME) dt

答案 2 :(得分:0)

让我们确定一些测试日期范围:

DECLARE @DateRangeTable TABLE
(
    StartDate DATETIME,
    EndDate DATETIME
);

INSERT INTO @DateRangeTable
VALUES
( '01-01-2010', '01-31-2010 23:59:00' ),
( '02-01-2010', '02-28-2010 23:59:00' ),
( '03-01-2010', '03-31-2010 23:59:00' ),
( '05-01-2010', '05-31-2010 23:59:00' ),
( '06-01-2010', '06-30-2010 23:59:00' ),
( '01-01-2011', '01-31-2011 23:59:00' ),
( '02-01-2011', '02-28-2011 23:59:00' ),
( '03-01-2011', '03-31-2011 23:59:00' ),
( '04-01-2011', '04-30-2011 23:59:00' ),
( '05-01-2011', '05-31-2011 23:59:00' ),
( '06-01-2011', '06-30-2011 23:59:00' ),
( '01-01-2012', '01-31-2012 23:59:00' ),
( '02-01-2012', '02-28-2012 23:59:00' ),
( '03-01-2012', '03-31-2012 23:59:00' ),
( '04-01-2012', '04-30-2012 23:59:00' ),
( '05-01-2012', '05-31-2012 23:59:00' );

设置开始搜索我们的期间

DECLARE @StartDate DATETIME;
SELECT @StartDate = MIN(StartDate) FROM @DateRangeTable;

此部分为我们范围内的所有小时数创建一个数字表

DECLARE @number_of_numbers INT = 100000;

;WITH
a AS (SELECT 1 AS i UNION ALL SELECT 1),
b AS (SELECT 1 AS i FROM a AS x, a AS y),
c AS (SELECT 1 AS i FROM b AS x, b AS y),
d AS (SELECT 1 AS i FROM c AS x, c AS y),
e AS (SELECT 1 AS i FROM d AS x, d AS y),
f AS (SELECT 1 AS i FROM e AS x, e AS y),
numbers AS 
(
    SELECT TOP(@number_of_numbers)
    ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS number
    FROM f
), 
dt as
(
    SELECT dt.CheckHour
    FROM
    (
        SELECT 
            DATEADD(HOUR, n.number, @StartDate) CheckHour
        FROM numbers n
    ) dt
    INNER JOIN @DateRangeTable drt
        ON dt.CheckHour >= drt.StartDate AND dt.CheckHour <= drt.EndDate
),
t as
(
    SELECT 
        dt.CheckHour,
        ROW_NUMBER() OVER(ORDER BY dt.CheckHour) i
    FROM dt
)

我们上面有几个CTE表达式,数字是数字表,dt是基于日期范围表的所有小时的列表,t只是用于检查的rownumber的小时数。

SELECT 
    d.PeriodStart,
    d.PeriodEnd,
    DATEDIFF(HOUR, d.PeriodStart, d.PeriodEnd) NumOfHours
FROM
(
    SELECT 
        MIN(t.CheckHour) PeriodStart,
        MAX(t.CheckHour) PeriodEnd
    FROM t
    GROUP BY DATEDIFF(HOUR, DATEADD(HOUR, i, 0), t.CheckHour)
) d

所以真正的代码是我首先得到小时之间的差异 - 将我的记录分组到连续范围的rownumber然后我得到最小值和最大值来得到开始和结束然后只是差异时间来获得最长基于小时的范围,这是输出:

PeriodStart               PeriodEnd                NumOfHours
2010-01-01 01:00:00.000   2010-03-31 23:00:00.000  2158
2010-05-01 00:00:00.000   2010-06-30 23:00:00.000  1463
2011-01-01 00:00:00.000   2011-06-30 23:00:00.000  4343
2012-01-01 00:00:00.000   2012-02-28 23:00:00.000  1415
2012-03-01 00:00:00.000   2012-05-31 00:00:00.000  2184