2012-12-13 59 views
1

我有關於SQL Server 2005的(TSQL)取決於狀態的兩個日期之間的分鐘數

一個問題,我有兩列 日期 狀態

和數據看上去..像

Date     Status 

2012-09-01 00:01:00.000 2 

2012-09-01 04:17:00.000 4 

2012-09-01 04:34:00.000 4 

2012-09-01 04:35:00.000 4 

2012-09-01 04:35:48.000 4 

2012-09-01 04:35:51.000 1 

2012-09-01 17:28:25.000 2 

2012-09-01 23:58:00.000 4 

2012-09-01 23:59:00.000 1 

我需要計算狀態之間的時間差...例如。最短的時間是當 狀態2開始和最大時間當狀態= 1(停止)之間我想要的分鐘數。 我已經通過光標檢查了狀態並記錄了變量的最小時間和最大時間。

我們是否可以使用CTE輕鬆完成這項工作。

我的問題需要很長時間才能完成......請幫助。

DECLARE @pdunitid INT 
     DECLARE @Date DATETIME 
     DECLARE @pddatetime DATETIME 
     DECLARE @pdstatus INT 
     DECLARE @starttime DATETIME 
     DECLARE @endTime DATETIME 
     DECLARE @calc INT 
     DECLARE @Totaltime INT 
     DECLARE @START INT 


     SET @pdunitid = 33568906 
     SET @Date = GETDATE() - 102 
     set @Totaltime = 0 
     SET @calc = 0 
     SET @START = 0 


     DECLARE s CURSOR FAST_FORWARD FOR 
     SELECT pddatetime,pdstatus FROM s1 WITH (NOLOCK) 
     WHERE pdunitid = @pdUnitid 
     AND CONVERT(VARCHAR,pddatetime,112) = CONVERT(VARCHAR,@Date,112) 
     ORDER BY pddatetime,pdstatus 

     OPEN s 

     FETCH NEXT FROM s INTO @pddatetime,@pdstatus 
     WHILE @@FETCH_STATUS = 0 
      BEGIN 
       -- status 2 is for start sometimes you don't get start so you will have to use the first date with status 4 

       IF pdstatus IN (2,4) AND @START = 0 
        BEGIN 
         SET @starttime = @pddatetime 
         SET @START = 1 
        END 

       -- status 1 is for stop 

       IF (@pdstatus= 1) 
        BEGIN 
         SET @endTime = @pddatetime 
         SET @calc = 1 
        END 

       -- if you dont get the status 1 by '23:59:00' take the end time 


      IF convert(varchar,@pdgpsdatetime,108) = '23:59:00' 
        BEGIN 
         SET @endTime = @pddatetime 
         SET @calc = 1 
      END 

       -- Calculate the minutes. 

       IF @calc = 1 
        BEGIN 
         SET @Totaltime = @Totaltime + DATEDIFF(mi, @starttime,@endTime) 
         SET @calc = 0 
         SET @START = 0 
        END 
     FETCH NEXT FROM s INTO @pddatetime,@pdstatus 
      END 
     CLOSE s 
     DEALLOCATE s 

     SELECT @Totaltime 
+0

請添加您的查詢,你已經寫了。 –

+0

你使用的是光標嗎?這些效率不高。列索引?發佈您嘗試的TSQL。 –

+0

我已張貼由查詢也...並評論哪裏有它需要.. – user978324

回答

1

試試這個,而不是#tbl把你的表名:

DROP TABLE #tbl 
CREATE TABLE #tbl([Date] DATETIME, [Status] INT) 
INSERT #tbl 
VALUES 
('2012-09-01 00:01:00.000', 2), 
('2012-09-01 04:17:00.000', 4), 
('2012-09-01 04:34:00.000', 4), 
('2012-09-01 04:35:00.000', 4), 
('2012-09-01 04:35:48.000', 4), 
('2012-09-01 04:35:51.000', 1), 
('2012-09-01 17:28:25.000', 2), 
('2012-09-01 23:58:00.000', 4), 
('2012-09-01 23:59:00.000', 1), 

-- for 2012-09-05 there are no statuses 1 or 2 
--('2012-09-05 00:01:00.000', 2), 
('2012-09-05 04:17:00.000', 4), 
('2012-09-05 04:34:00.000', 4), 
('2012-09-05 04:35:00.000', 4), 
('2012-09-05 04:35:48.000', 4), 
('2012-09-05 04:35:51.000', 4), 
('2012-09-05 17:28:25.000', 4), 
('2012-09-05 23:58:00.000', 4) 
--('2012-09-05 23:59:00.000', 1) 

;WITH tbl AS 
(
    SELECT *, 
      ROW_NUMBER() OVER (ORDER BY [Date]) id 
    FROM #tbl 
), 
b AS 
(
    SELECT MIN([Date]) MinDate, 
      MAX([Date]) MaxDate, 
      CAST([Date] AS DATE) dateWithoutTime 
    FROM tbl 
    GROUP BY CAST([Date] AS DATE) 
), 
a AS 
(
    SELECT *, 
      ROW_NUMBER() OVER (ORDER BY [Date]) num 
    FROM tbl 
    LEFT JOIN 
      b ON 
      b.MaxDate = [Date] 
    OR  b.MinDate = [Date] 
    WHERE [Status] IN (2, 1) 
    OR  [Date] = CASE WHEN NOT EXISTS (SELECT 1 FROM #tbl c WHERE c.Status = 2 AND CAST(c.[Date] AS DATE) = b.dateWithoutTime) THEN b.MinDate END 
    OR  [Date] = CASE WHEN NOT EXISTS (SELECT 1 FROM #tbl c WHERE c.Status = 1 AND CAST(c.[Date] AS DATE) = b.dateWithoutTime) THEN b.MaxDate END 
) 

SELECT 
     tbl.Date, 
     tbl.Status, 
     CASE WHEN a2.num % 2 = 0 THEN DATEDIFF(MINUTE, a1.Date, a2.Date) END Diff 
FROM tbl 
LEFT JOIN 
     a a2 ON tbl.id = a2.id 
LEFT JOIN 
     a a1 ON a2.num = a1.num + 1 
ORDER BY [Date] 
+0

不客氣,我希望它會幫助... –

+0

謝謝男人你很快..稍微改變了數據有時你不會獲得狀態2('2012-09-01 00:01:00.000',4),並且當天結束時將爲('2012-09-01 23:59:00.000',4)他們開始將是第一個記錄和結束將是最後一個記錄,在你之間也可能有2和1 ..你能幫助..請 – user978324

+0

嗨伊萬,我已評論你的查詢,你可以看看和任何想法這請.. – user978324

相關問題