如何计算特定范围T-SQL的持续时间

时间:2014-11-20 02:59:20

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

以下查询将构建一个包含项目1,2和3的临时表。这样做的目的是生成一个我正面临的问题的简单数据集。

运行它将产生以下结果:

Target  PollTime    PrevPollTime    Duration
-------------------------------------------------------------
Item1   2014-11-18 00:12:14.000 2014-11-18 00:05:14.000 7
Item3   2014-11-18 00:08:14.000 2014-11-18 00:02:14.000 6
Item3   2014-11-18 00:14:14.000 2014-11-18 00:08:14.000 6

但是,如果您将@EndDate参数更改为' 2014-11-18 00:11:14' ,结果为:

Item3   2014-11-18 00:08:14.000 2014-11-18 00:02:14.000 6

我的问题是我想添加结果的功能:

Item1   2014-11-18 00:11:14.000 2014-11-18 00:05:14.000 6
Item3   2014-11-18 00:08:14.000 2014-11-18 00:02:14.000 6

如果@EndDate参数更改为' 2014-11-18 00:25:14'

Item1   2014-11-18 00:12:14.000 2014-11-18 00:05:14.000 7
Item1   2014-11-18 00:25:14.000 2014-11-18 00:14:14.000 11
Item2   2014-11-18 00:25:14.000 2014-11-18 00:14:14.000 11
Item3   2014-11-18 00:08:14.000 2014-11-18 00:02:14.000 6
Item3   2014-11-18 00:14:14.000 2014-11-18 00:08:14.000 6
Item3   2014-11-18 00:25:14.000 2014-11-18 00:14:14.000 11

@EndDate参数必须以某种方式包含。

DROP TABLE #TempTable
CREATE TABLE #TempTable(
Target VARCHAR(255),
PollTime DATETIME)

INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:00:14.000' AS    DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:01:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:02:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:03:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:04:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:05:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:12:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:13:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item1', CAST('2014-11-18 00:14:14.000' AS DATETIME))

INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:00:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:01:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:02:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:03:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:04:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:05:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:06:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:07:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:08:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:09:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:10:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:11:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:12:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:13:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item2', CAST('2014-11-18 00:14:14.000' AS DATETIME))

INSERT INTO #TempTable (Target, PollTime) VALUES('Item3', CAST('2014-11-18 00:01:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item3', CAST('2014-11-18 00:02:14.000' AS DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item3', CAST('2014-11-18 00:08:14.000' AS    DATETIME))
INSERT INTO #TempTable (Target, PollTime) VALUES('Item3', CAST('2014-11-18 00:14:14.000' AS DATETIME))

DECLARE @StartDate DATETIME = CAST('2014-11-18 00:00:00' AS DATETIME)
DECLARE @EndDate DATETIME = CAST('2014-11-18 00:15:00' AS DATETIME);

WITH Data AS (
SELECT *
FROM #TempTable 
WHERE PollTime BETWEEN @StartDate AND @EndDate
), 
RankData AS 
(
SELECT * FROM Data A
    CROSS APPLY 
    (
        SELECT 
            PrevPollTime = PollTime
        FROM 
        (
            SELECT *, 
                Rn = ROW_NUMBER()OVER(ORDER BY PollTime DESC)
            FROM #TempTable B
            WHERE B.Target = A.Target AND B.PollTime < A.PollTime 
        ) T WHERE Rn = 1 
    ) AS C          
WHERE (DATEDIFF(MINUTE, C.PrevPollTime, A.PollTime) > 5)
)
SELECT *, 
Duration = DATEDIFF(MINUTE, PrevPollTime, PollTime) 
FROM RankData

2 个答案:

答案 0 :(得分:1)

使用两个CASE clausules修改您的CTE。这是修改后的代码: (修改版,尝试:),现在它工作: - ))

DECLARE @StartDate DATETIME = CAST('2014-11-18 00:00:00' AS DATETIME)
DECLARE @EndDate DATETIME = CAST('2014-11-18 00:25:14' AS DATETIME);


IF OBJECT_ID('tempdb..#TempTable2') IS NOT NULL DROP TABLE #TempTable2
SELECT Target,PollTime 
INTO #TempTable2
FROM #TempTable
UNION ALL
SELECT DISTINCT Target,@EndDate AS PollTime
FROM #TempTable
WHERE @EndDate > PollTime;



WITH Data AS (
SELECT DISTINCT Target,CASE WHEN PollTime > @EndDate THEN @EndDate ELSE PollTime END AS PollTime
FROM #TempTable2
WHERE PollTime BETWEEN @StartDate AND (CASE WHEN PollTime > @EndDate THEN PollTime ELSE @EndDate END)
), 
RankData AS 
(
SELECT * FROM Data A
    CROSS APPLY 
    (
        SELECT 
            PrevPollTime = PollTime
        FROM 
        (
            SELECT *, 
                Rn = ROW_NUMBER()OVER(ORDER BY PollTime DESC)
            FROM #TempTable2 B
            WHERE B.Target = A.Target AND B.PollTime < A.PollTime 
        ) T WHERE Rn = 1 
    ) AS C          
WHERE (DATEDIFF(MINUTE, C.PrevPollTime, A.PollTime) > 5)
)
SELECT *, 
Duration = DATEDIFF(MINUTE, PrevPollTime, PollTime) 
FROM RankData

答案 1 :(得分:0)

我添加了一个UNION,在那里我获得了Max的日期并进行了比较,稍微改写了我的查询。

DECLARE @StartDate DATETIME = CAST('2014-11-18 00:00:00' AS DATETIME)
DECLARE @EndDate DATETIME = CAST('2014-11-18 00:20:14' AS DATETIME);

WITH Data AS (
SELECT 
    DISTINCT Target, 
    PollTime = CASE WHEN PollTime > @EndDate THEN @EndDate ELSE PollTime END
FROM #TempTable 
WHERE PollTime BETWEEN @StartDate AND (CASE WHEN PollTime > @EndDate THEN PollTime ELSE @EndDate END)
), 
RankData AS 
(
SELECT * FROM Data A
    CROSS APPLY 
    (
        SELECT 
            PrevPollTime = PollTime
        FROM 
        (
            SELECT *, 
                Rn = ROW_NUMBER()OVER(ORDER BY PollTime DESC)
            FROM #TempTable B
            WHERE B.Target = A.Target AND B.PollTime < A.PollTime 
        ) T WHERE Rn = 1 
    ) AS C          
UNION 
SELECT 
    Target,
    PollTime = @EndDate,
    PrevPollTime = MAX(PollTime)
FROM Data A
WHERE PollTime BETWEEN @StartDate AND @EndDate      
GROUP BY Target             
)
SELECT *, 
Duration = DATEDIFF(MINUTE, PrevPollTime, PollTime) 
FROM RankData WHERE (DATEDIFF(MINUTE, PrevPollTime, PollTime) > 5)