2012-03-20 3 views
0

Итак, у меня есть процедура, в которой я сейчас находится в процессе отладки, и я сузил ее до этого оператора select.как правильно использовать случай в where, где статья

Примечание: где to_date (''), 3300, 5220 представляет собой представление того, что будет из параметра.

Теперь то, что это, предполагают, чтобы сделать, это принять параметр, который является отметкой о времени и вычитать значение смещения

смещение количество минут, которые прошли с тех пор начала недели где воскресенье в полночь = 0. (Так что если в полдень было полдень, смещение = 1440).

Когда смещение вычитается из параметра, вы получаете начало недели. Затем вы получите значение смещения из таблицы, которая уже была предопределена, и добавьте это значение в начало недели, чтобы получить метку времени.

Это делается для того, чтобы получить дату начала и дату окончания смены.

Мой исходный код работает без проблем с ниже, однако отсутствует граничное условие субботы, идущего в воскресенье.

SELECT SHIFT_ID_PK, SHIFT_NAME_FK, 
     SHIFT_START_DAY, SHIFT_START_TIME, 
     SHIFT_END_DAY, SHIFT_END_TIME, 
     SITE_ID_FK, SHIFT_DAY_ID, 
     STARTOFFSET, ENDOFFSET, 
     TO_TIMESTAMP_TZ(TO_CHAR((PSTARTTIMESTAMP - (VSTARTOFFSET/24/60)) + (STARTOFFSET/24/60), 'YYYY-MM-DD HH:MI:SS AM'), 'YYYY-MM-DD HH:MI:SS AM TZH:TZM') as SHIFT_START_DATE, 
     TO_TIMESTAMP_TZ(TO_CHAR((PENDTIMESTAMP - (VENDOFFSET/24/60)) + (ENDOFFSET /24/60), 'YYYY-MM-DD HH:MI:SS AM') ,'YYYY-MM-DD HH:MI:SS AM TZH:TZM') as SHIFT_END_DATE 
    from shift_tbl 
    WHERE 
     ENDOFFSET >= VSTARTOFFSET 
    and STARTOFFSET < VENDOFFSET 
    order by shift_start_date asc; 

Теперь, что я придумал для обработки этого граничного условия, ниже которого я тестировал скрипт.

declare 
    VSTARTOFFSET integer; 
    VENDOFFSET integer; 
    SHIFTOFFSET integer; 
    PSTARTTIMESTAMP timestamp; 
    PENDTIMESTAMP timestamp; 
    begin 
    VSTARTOFFSET := 10020; 
    VENDOFFSET := 420; 
    PSTARTTIMESTAMP := TO_DATE('3/17/2012 23:00', 'mm/dd/yyyy hh24:mi'); 
    PENDTIMESTAMP := TO_DATE('3/18/2012 7:00', 'mm/dd/yyyy hh24:mi'); 

    SELECT SHIFT_ID_PK, SHIFT_NAME_FK, 
     SHIFT_START_DAY, SHIFT_START_TIME, 
     SHIFT_END_DAY, SHIFT_END_TIME, 
     SITE_ID_FK, SHIFT_DAY_ID, 
     STARTOFFSET, ENDOFFSET, 
     TO_TIMESTAMP_TZ(TO_CHAR((PSTARTTIMESTAMP - (VSTARTOFFSET/24/60)) + (STARTOFFSET/24/60), 'YYYY-MM-DD HH:MI:SS AM'),'YYYY-MM-DD HH:MI:SS AM TZH:TZM') as SHIFT_START_DATE, 
     TO_TIMESTAMP_TZ(TO_CHAR((PENDTIMESTAMP- (VENDOFFSET/24/60)) + (ENDOFFSET /24/60), 'YYYY-MM-DD HH:MI:SS AM'),'YYYY-MM-DD HH:MI:SS AM TZH:TZM') AS SHIFT_END_DATE 
    from SHIFT_TBL 
    where 
    case 
     when SHIFT_START_DAY = 7 and SHIFT_END_DAY = 1 then   
       SHIFTOFFSET:= ENDOFFSET + 10080; 
      and VENDOFFSET := VENDOFFSET + 10080; 
     else 
       SHIFTOFFSET := ENDOFFSET; 
    end 
       SHIFTOFFSET >= VSTARTOFFSET 
      and STARTOFFSET < VENDOFFSET 
    order by SHIFT_START_DATE asc; 
    end; 

Как вы можете видеть, я не уверен, как обрабатывать оператор case внутри предложения where. В основном то, что я пытаюсь сделать, это то, что начальный день - суббота, а конец дня - воскресенье, затем добавьте 10080 (одна неделя) к офсетному офсету/продавцу и если это не соответствует этому условию, используйте исходные значения.

В основном мой вопрос довольно прост ... Я верю, но мне трудно получить решение. Поэтому я хотел бы знать, как правильно использовать оператор case внутри предложения where. И если я не предполагаю использовать оператор case в этой форме внутри предложения where, как именно я бы настроил этот оператор select.

Любая помощь или предложения приветствуются. Спасибо.

+0

Это кажется излишне сложным, но, возможно, мне что-то не хватает. В основном, вы пытаетесь рассчитать начальную и конечную временную метку, и я полагаю, что в этой таблице данных нет временных меток? Я вижу, что ваши дневные поля являются целыми числами, с 1 по воскресеньям до 7 в субботу. Какие данные хранятся в ваших полях времени переключения? –

+0

Вы не можете делать утверждения назначения PL/SQL внутри предложения SQL WHERE. – GriffeyDog

ответ

3

Вам не нужно устанавливать какие-либо переменные в ИНЕКЕ, на самом деле, даже вы не можете это сделать. Что вы хотите сделать, это написать правильный логический предикат (это выражение, возвращающее true или false), описывающее строки, которые вы хотите получить.

Вот 2 примера, как я хотел бы попытаться определить его (насколько я понимаю ваши требования):

  1. без футляра:

    WHERE 
    (SHIFT_START_DAY = 7 and SHIFT_END_DAY = 1 AND ENDOFFSET + 10080 >= VSTARTOFFSET and STARTOFFSET < VENDOFFSET + 10080) OR 
    (NOT (SHIFT_START_DAY = 7 and SHIFT_END_DAY = 1) AND SHIFTOFFSET >= VSTARTOFFSET and STARTOFFSET < VENDOFFSET) 
    
  2. с СЛУЧАЙ:

    WHERE 
    (CASE WHEN SHIFT_START_DAY = 7 and SHIFT_END_DAY = 1 THEN ENDOFFSET + 10080 ELSE ENDOFFSET END) >= VSTARTOFFSET 
    AND STARTOFFSET < (CASE WHEN SHIFT_START_DAY = 7 and SHIFT_END_DAY = 1 THEN VENDOFFSET + 10080 ELSE VENDOFFSET END) 
    

Я не отлаживал это выражения, поэтому не ожидайте их работы;), но я надеюсь, что у вас есть идея.

+0

Это именно то, что я искал! Наверное, у меня был просто серьезный мозговой пердит, чтобы не поймать это. Благодаря! – James213

0

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

declare 
--variables 
cursor c_shifts is 
select SHIFT_ID_PK, SHIFT_START_DAY, SHIFT_END_DAY 
from SHIFT_TBL; 
begin 
for r_result in c_shifts 
loop 
if r_result.SHIFT_START_DAY = 1 and r_result.SHIFT_END_DAY = 7 then 
    --set variables to values for special case shifts 
else 
    --set variables for all other cases 
end if; 
    --run your query for the particular result in this loop iteration based upon r_result.SHIFT_ID_PK, using the variables you set above 
    --save results to a staging table, directly dbms_output from the block, etc., as needed 
end loop; 
    --commit results if saving to a staging table, etc., as needed once the loop completes 
end; 
0

Не рассчитывайте, запрос :)

Предложение: рассмотреть вопрос об использовании auxiliary calendar table

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

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

  • Сколько рабочих дней между х и у?

  • Что все даты между вторым вторником марта и первой пятницей апреля?

  • ...

... возможно, с a column for julianized business days.

Смежные вопросы