2015-03-18 3 views
0

Не удалось найти что-либо путем поиска (хотя это могут быть мои условия поиска), поэтому приносите свои извинения, если это было задано/ответили.MSSQL - группировать время между начальными/конечными столбцами по дате

Мы ведем журнал простоя оборудования в MSSQL 2012, и я пытаюсь сообщать минут простоя, сгруппированных по дням, оборудование, DTCode. Проблема, с которой я столкнулась, - это таблица журналов содержит начало & даты окончания каждого инцидента, а инциденты часто охватывают несколько дней (или иногда недель) между началом и концом.

Пример данных:

Start   End    Equipment DTCode 
01/01/15 00:00 01/02/15 02:00 Line1  2 

желаемого результата:

Date   Equipment  DTCode Downtime(minutes) 
01/01/15  Line1   2  1440 
01/02/15  Line1   2  120 

РЕДАКТИРОВАТЬ

Хорошо, теперь у меня есть безвкусный решение с низкой производительности, потому что единственный способ, которым я мог понять это с помощью вложенного курсора. Вот новая скрипка с большим набором данными и функциональным решением, я ищу, чтобы настроить/оптимизируют:

http://sqlfiddle.com/#!6/b287e/1

ответ

0

Если вы имеете в виде получение времени между двумя «ПРОСТОЯМИ» с, вы можете получить значение с PHP, используя соединение MYSQL, и вычислить разницу, а затем удалить две строки и заменить ее новой строкой с помощью вычисленных результатов.

$query = "DELETE FROM TaBlEnAmEhErE WHERE DTCode=2"; 
0

Когда я начал тестирование решения, которое я придумал против производительности данных производства было гораздо более приемлемым, так что я собираюсь свернуть с ним сейчас ограничивающими пользователями 1 год объемом данных в течение доклада ,

В дополнение к данным журнала, я создал таблицу, содержащую даты от 2010-2050, так что я не должен генерировать даты каждого запуска, это то, что я придумал:

--Variables for outer cursor 
DECLARE @ID INT 
,@StartDate DATETIME 
,@EndDate DATETIME 
,@LineID TINYINT 
,@DTCode SMALLINT 
--Table var to hold results 
DECLARE @ResultTbl AS TABLE (
    [Date] DATE 
    ,Line TINYINT 
    ,DTCode SMALLINT 
    ,MinDiff INT 
) 
--Declare cursor to loop through log data 
DECLARE IDCur CURSOR local fast_forward FOR 
SELECT ID 
    ,StartTime 
    ,EndTime 
    ,EquipmentID 
    ,dtcode 
FROM DowntimeLog 
OPEN IDCur 
    FETCH NEXT FROM IDCur INTO @ID, @StartDate, @EndDate, @LineID, @DTCode 
    WHILE @@FETCH_STATUS = 0 
    BEGIN 
     --Check if the entry spans multiple days 
     IF DATEDIFF(DAY,@StartDate,@EndDate) > 0 
     BEGIN 
      --Declare cursor to loop through each date that pertains to the entry 
      DECLARE @D DATE 
      DECLARE applicableDates CURSOR LOCAL fast_forward FOR 
      SELECT tDate 
      FROM DateTbl 
      WHERE tDate BETWEEN CAST(@StartDate AS DATE) AND CAST(@EndDate AS DATE) 
      OPEN applicableDates 
      FETCH NEXT FROM applicableDates INTO @D 
      WHILE @@FETCH_STATUS = 0 
      BEGIN 
       --Determine if @D is the first date 
       IF (SELECT CAST(@StartDate AS DATE)) = @D 
       BEGIN 
        --If @D is the first date insert result row with minutes between start & 00:00 the next day 
        INSERT INTO @ResultTbl (
          [Date] 
          ,Line 
          ,DTCode 
          ,MinDiff) 
         VALUES (
          @D 
          ,@LineID 
          ,@DTCode 
          ,(SELECT DATEDIFF(MINUTE,@StartDate,DATEADD(DAY,1,@D)))) 
       END 
       ELSE 
       BEGIN 
        --Determine if @D is the last date 
        IF (SELECT DATEDIFF(MINUTE,@D,@EndDate)) < 1440 
        BEGIN 
         --If @D is the last date insert result row with minutes between @D 00:00 and end of downtime 
         INSERT INTO @ResultTbl (
          [Date] 
          ,Line 
          ,DTCode 
          ,MinDiff) 
         VALUES (
          @D 
          ,@LineID 
          ,@DTCode 
          ,(SELECT DATEDIFF(MINUTE,@D,@EndDate))) 
        END 
        ELSE 
        BEGIN 
         --If @D is not first or last date insert result row for the full day 
         INSERT INTO @ResultTbl (
          [Date] 
          ,Line 
          ,DTCode 
          ,MinDiff) 
         VALUES (
          @D 
          ,@LineID 
          ,@DTCode 
          ,1440) 
        END 
       END 
       FETCH NEXT FROM applicableDates INTO @D 
      END 
      CLOSE applicableDates 
      DEALLOCATE applicableDates 
     END 
     ELSE 
     BEGIN 
      --Entry does not span multiple days, insert result row with diff between start & end 
      INSERT INTO @ResultTbl (
          [Date] 
          ,Line 
          ,DTCode 
          ,MinDiff) 
         VALUES (
          CAST(@StartDate AS DATE) 
          ,@LineID 
          ,@DTCode 
          ,(SELECT DATEDIFF(MINUTE,@StartDate,@EndDate))) 
     END 
     FETCH NEXT FROM IDCur INTO @ID, @StartDate, @EndDate, @LineID, @DTCode 
    END 
CLOSE IDCur 
DEALLOCATE IDCur 
--Display Result 
SELECT [Date] 
     ,Line 
     ,DTCode 
     ,SUM(MinDiff) AS MinDown 
FROM @ResultTbl 
GROUP BY [Date],Line,DTCode