2013-04-18 29 views
0

美好的一天,我工作的一些代碼,其中 -的Oracle SQL11克 - 下一個工作日查詢

1)如果請求是在工作日的下午5:00時區東部(美國)後提交(週一至週四)和美國東部時區上午7點59分59秒之前的工作日,比日期將更改爲下一工作日@上午8:00。

2)如果一個請求5:00 PM之間在星期五提交和前上午07時59分59秒,繼星期一,比如上面提到的時間捲起。

3)然後,代碼需要檢查另一個日期字段進行比較的「接受的」時間(4小時的提交日期或「新」的日期)的範圍內。

例如:

如果請求001提交2013年4月17日上午02點00,那麼它的新的日期將是2013年4月17日08:00 AM。

如果請求002提交2013年4月17日下午6時45分,那麼它的新的日期將是2013年4月18日08:00 AM。

如果請求003提交2013年4月20日上午5點45分(這是一個星期六),那麼它的新的日期將是2013年4月22日08:00 AM。

我一直piecemailing代碼一起,在希望我能在最後的代碼把他們放在一起。


這是我迄今爲止(對於日期轉換代碼)

  ,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

case產生weekend_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函數要求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 

然後,您可以使用它作爲內嵌視圖或作爲CTE:

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()中用於顯示,但是(a)不清楚這些字段是否將顯示在SQL * Plus或其他地方,或者將會添加到其他東西中,並應該保留爲日期;如果您修改會話以檢查NLS_DATE_LANGUAGE,那麼您可以在NLS_DATE_FORMAT時設置NLS_DATE_FORMAT。再次取決於你在哪裏運行單桅帆船。

您可能還會在錯誤的級別檢查sysdate。事實上,它將包括今日08:00的所有股票,因爲它正在進行預調整時間。如果您將其移動到外部select那麼您可以檢查clock_start是否在該日期範圍內。當然,您也可以故意這樣做。

希望幫助...

+0

你我的朋友是絕對的天才 - 這對我所需要的是完美的。我離賽道很遠......謝謝你,我非常感謝你的幫助! –