2010-06-09 3 views
3

Я работаю над запросом, который вернет предлагаемую дату начала производственной линии на основании установленной даты и количества минут, необходимых для выполнения задачи.Возможно ли это с Sql 2005 CTE?

Существует таблица календаря (LINE_ID, CALENDAR_DATE, SCHEDULED_MINUTES), которая отображает на производственную линию количество минут, запланированных на этот день.

Пример: (Обычно 3 смены стоит времени не запланирована в день, без выходных, но может варьироваться)

1, 06/8/2010 00:00:00.000, 1440 
1, 06/7/2010 00:00:00.000, 1440 
1, 06/6/2010 00:00:00.000, 0 
1, 06/5/2010 00:00:00.000, 0 
1, 06/4/2010 00:00:00.000, 1440 

Для того, чтобы получить предлагаемую дату начала, я должен начать с датой и итерацией вниз по дням, пока я не накопил достаточно времени для выполнения задачи.

Мой вопрос может быть таким, как это делается с помощью CTE, или это то, что должно обрабатываться курсором. Или ... я просто иду совсем по-другому?

+0

Некоторые ссылки по теме http://stackoverflow.com/questions/1153879/how-do-i-calculate-a-running-total-in-sql-without-using-a-cursor http: // www. jasinskionline.com/TechnicalWiki/RunningTotal.ashx. –

ответ

1

будет что-то вроде этой работы?

;WITH CALENDAR_WITH_INDEX(CALENDAR_DATE, AVAILABLE_MINUTES, DATE_INDEX) 
(
    SELECT 
      CALENDAR_DATE, 
      1440 - SCHEDULED_MINUTES,    /* convert scheduled minutes to available minutes */ 
      ROW_NUMBER() OVER (ORDER BY CALENDAR_DATE DESC) /* get day indexes. can't use DATE functions to get previous day (think holidays) */ 
    FROM 
      CALENDAR 
    WHERE 
      LINE_ID = @LINE_ID AND 
      CALENDAR_DATE < @DUEDATE      /* use <= instead of < if you can do stuff on the scheduled date too */ 
), 
WITH TIME_SLICES (SCHEDULED_DATE, MINUTESPENDING, SLICE_INDEX) 
(
    SELECT 
      CALENDAR_DATE, 
      @DURATION - (AVAILABLE_MINUTES),    /* knocks of minutes available from our running total */ 
      DATE_INDEX 
    FROM 
      CALENDAR_WITH_INDEX        
    WHERE 
      DATE_INDEX = 1         /* gets the first date usable date */ 

    UNION ALL 

    SELECT 
      CALENDAR_DATE, 
      MINUTESPENDING - AVAILABLE_MINUTES 
      DATE_INDEX 
    FROM 
      CALENDAR_WITH_INDEX 
      INNER JOIN TIME_SLICES 
       ON DATE_INDEX = SLICE_INDEX + 1   /* this gets us the date 1 day before */ 
    WHERE 
      MINUTESPENDING > 0        /* stop when we have no more minutes */ 
) 
SELECT MIN(SCHEDULED_DATE) FROM TIME_SLICES 

Я думаю, что производительность будет плохой из-за row_number, рекурсивной части.

1

Возможно, но медленное использование выражения Common Table для вычисления общей суммы. Это один из немногих случаев, когда курсор работает лучше.