2013-04-18 5 views
0

Добрый день, я работаю на некоторый код где -Oracle SQL 11g - следующий рабочий день запрос

1) если запрос был представлен после 5:00 вечера по восточному временной зоны (Америка) в будний день (с понедельника по четверг) и до 7:59:59 AM Восточный часовой пояс (Америка) в будний день, чем дата будет изменена на следующий рабочий день @ 8:00.

2) если запрос был отправлен в период с 5:00 вечера по пятницу и до 7:59:59 утра, что после понедельника, чем время скатывается вверх, как указано выше.

3) Затем код должен проверить другое поле даты, чтобы сравнить «принятое» время (в течение 4 часов с даты отправки или «новой» даты).

Например:

Если запрос 001 был представлен 04/17/2013 2:00 AM, то его новая дата будет 04/17/2013 8:00 утра.

Если запрос 002 был отправлен 17.04.2012 18:45, то его новая дата будет 04/18/2013 08:00.

Если запрос 003 был отправлен 04/20/2013 05:45 (это суббота), то его новая дата будет 22.04.2013 08:00.

Я был связан с кодом вместе, в надежде, что я смогу собрать все это вместе в конечном коде.


Это то, что я до сих пор (для преобразования кода даты)

  ,CASE 
     WHEN to_date(('DATE_REQUESTED'),'DAY',nls_date_language = English) in ('Friday','Saturday')) 
     THEN NEXT_DAY(to_date(('DATE_REQUESTED'),'Monday') + 8/24) 
     ELSE DATE_REQUESTED 
    END as Weekend_Converted 

Для кода, чтобы проверить, если запрос был принят в течение 4 часов

 SELECT RIT_Request_v.* 
    ,CASE 
    WHEN DATE_ACCEPTED IS NULL THEN 'NOT ACKNOWLEDGED' 
    WHEN DATE_ACCEPTED > (DATE_REQUESTED + 4/24) THEN 'OVER 4 HOURS' 
    ELSE 'WITHIN 4 HOURS' 
    END AS Acknowledgement 

    FROM RIT.RIT_Request_v 

    WHERE (("DATE_REQUESTED") BETWEEN trunc(sysdate, 'YYYY') AND trunc(sysdate)) 

Как отмечено в одном из моих комментариев ниже, я обновил свои кода, и теперь получают ошибки «Неверный идентификатор» -

SELECT RIT_Request_v.* 
    ,CASE WHEN TO_CHAR(DATE_REQUESTED,'D') IN (1,6,7) 
      THEN NEXT_DAY(DATE_REQUESTED,'MONDAY') 
      ELSE DATE_REQUESTED + 1 END AS Weekend_Converted 

    ,CASE WHEN DATE_ACCEPTED IS NULL THEN 'NOT ACKNOWLEDGED' 
      WHEN WEEKEND_CONVERTED IS NULL THEN 'NOT ACKNOWLEDGED' 
      WHEN DATE_ACCEPTED > (DATE_REQUESTED + 4/24) THEN 'OVER 4 HOURS' 
      WHEN DATE_ACCEPTED > (Weekend_Converted + 4/24) THEN 'OVER 4 HOURS' 
      ELSE 'WITHIN 4 HOURS' END AS Acknowledgement 

    FROM RIT.RIT_Request_v 

    WHERE (("DATE_REQUESTED") BETWEEN trunc(sysdate, 'YYYY') AND trunc(sysdate)) 

       AND FORM_ID IN   (2011,2014,5007,5036,5039,7007,10000,10001,10005,10007,10011,10024,10025,10029,10032,10033,10034,10035,10036,10037,11011,11013,11999,36001) 
+0

Я нашел этот пункт: http://stackoverflow.com/questions/4677984/need-to-find-next-and-previous-working-day-in-oracle и обновил мой код следующим образом, но теперь я получаю ошибку «Неверный идентификатор». Я не верю, что есть опечатки ... мне нужно сделать что-то еще? –

ответ

0

Вашего caseweekend_converted порождающего только кажется, иметь дело с уикенд в оригинальной версии, и, кажется, следует путать, как-нибудь в пятницу включена; обновленный каждый переносит каждую дату в одно и то же время либо на следующий день, либо в следующий понедельник, теряя как часть 08:00, так и большую часть дня недели вы не переносите день.

Вы получили недопустимый идентификатор в своей второй версии, потому что вы определяли псевдокоманду weekend_converted, а затем пытались использовать ее на том же уровне запроса, что недопустимо. Вам нужно будет определить в нем на одном уровне, а затем обратиться к нему во внешнем select.

Это, кажется, чтобы покрыть свои правила, но я не проверял его с какими-либо дополнительными датами:

select r.*, 
    case 
     when to_char(date_requested, 'DY', 
       'NLS_DATE_LANGUAGE=English') in ('SAT', 'SUN') 
      or (to_char(date_requested, 'DY', 
       'NLS_DATE_LANGUAGE=English') = 'FRI' 
       and extract(hour from cast(date_requested as timestamp)) >= 17) 
     then trunc(next_day(date_requested, 'MON')) + interval '8' hour 
     when extract(hour from cast(date_requested as timestamp)) >= 17 
     then trunc(date_requested) + interval '1' day + interval '8' hour 
     when extract(hour from cast(date_requested as timestamp)) < 8 
     then trunc(date_requested) + interval '8' hour 
     else date_requested 
    end as clock_start 
from rit_request_v r; 

Хотя, в то время как принуждение NLS_DATE_LANGUAGE является хорошей идеей, если вы не знаете, где это будет работать , функция next_day требует, чтобы параметр дня находился на вашем локальном языке, поэтому вам лучше настроить его для всего сеанса, а не для каждой функции.

Во всяком случае, это дает:

DATE_REQUESTED DATE_ACCEPTED  FORM_ID CLOCK_START 
---------------- ---------------- ---------- ---------------- 
2013-04-17 02:00 2013-04-17 11:59  5007 2013-04-17 08:00 
2013-04-17 18:45 2013-04-18 11:59  5007 2013-04-18 08:00 
2013-04-13 05:45      5007 2013-04-15 08:00 

Вы можете использовать это как вложенное представление или как КТР:

with t as (
select r.*, 
    case 
     when to_char(date_requested, 'DY', 
       'NLS_DATE_LANGUAGE=English') in ('SAT', 'SUN') 
      or (to_char(date_requested, 'DY', 
       'NLS_DATE_LANGUAGE=English') = 'FRI' 
       and extract(hour from cast(date_requested as timestamp)) >= 17) 
     then trunc(next_day(date_requested, 'MON')) + interval '8' hour 
     when extract(hour from cast(date_requested as timestamp)) >= 17 
     then trunc(date_requested) + interval '1' day + interval '8' hour 
     when extract(hour from cast(date_requested as timestamp)) < 8 
     then trunc(date_requested) + interval '8' hour 
     else date_requested 
    end as clock_start 
from rit_request_v r 
where date_requested between trunc(sysdate, 'YYYY') and trunc(sysdate) 
and form_id in (2011, 2014, 5007, 5036, 5039, 7007, 10000, 10001, 10005, 10007, 10011, 10024, 10025, 10029, 10032, 10033, 10034, 10035, 10036, 10037, 11011, 11013, 11999, 36001) 
) 
select t.*, 
    case 
     when date_accepted is null then 'NOT ACKNOWLEDGED' 
     when date_accepted > (clock_start + interval '4' hour) 
     then 'OVER 4 HOURS' 
     else 'WITHIN 4 HOURS' 
    end as acknowledgement 
from t; 

Что дает:

DATE_REQUESTED DATE_ACCEPTED  FORM_ID CLOCK_START  ACKNOWLEDGEMENT 
---------------- ---------------- ---------- ---------------- ---------------- 
2013-04-17 02:00 2013-04-17 11:59  5007 2013-04-17 08:00 WITHIN 4 HOURS 
2013-04-17 18:45 2013-04-18 11:59  5007 2013-04-18 08:00 WITHIN 4 HOURS 
2013-04-13 05:45      5007 2013-04-15 08:00 NOT ACKNOWLEDGED 

я могу сослаться до clock_start, потому что он определен на более низком уровне, в данном случае в CTE.

Вы заметите, что мои даты в вашем совершенно другом формате. Обычно я бы сказал, что вы должны обернуть эти поля в to_char() для отображения, но (а) неясно, будет ли это отображаться в SQL * Plus или где угодно, или будет подаваться во что-то другое и должно оставаться в качестве дат; и если вы измените сеанс проверки NLS_DATE_LANGUAGE, вы можете установить NLS_DATE_FORMAT, пока вы там. Снова зависит от того, где вы его запускаете.

Возможно, у вас также есть чек против sysdate на неправильном уровне. Он будет включать в себя все, у которых есть clock_start от 08:00 сегодня, так как он работает над временем предварительной настройки. Если вы переместите это на внешний select, тогда вы можете проверить, что clock_start находится в этом диапазоне дат. Разумеется, вы тоже могли бы сделать это намеренно.

Надежда, что помогает ...

+0

Ты мой друг - абсолютный гений - это прекрасно для того, что мне нужно. Я был так далеко от трассы ... спасибо за это, я очень благодарен за помощь! –

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