2012-03-20 23 views
0

所以我有一個程序,我目前正在調試的過程中,我已經縮小到這個選擇語句。如何正確使用案例中的條款

注意:其中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; 

正如你所看到的我不確定如何處理where子句中的case語句。基本上我想要做的是如果開始日是星期六,結束日是星期日,然後將10080(一週)添加到結束偏移量/銷售偏移量,並且如果它不符合該條件,則使用原始值。

基本上我的問題很簡單......我相信但我很難獲得解決方案。所以我想知道的是如何在where子句中正確使用case語句。如果我不想在where子句中使用這種形式的case語句,我會如何設置這個select語句。

任何幫助或建議,非常感謝。 謝謝。

+0

這似乎不必要的複雜,但也許我錯過了一些東西。基本上,你正在試圖計算一個開始和結束的時間戳,並且我假設這個數據表中沒有存儲時間戳?我發現你的日子田地是一個整數,1週日到7週六。你的班次時間字段中存儲了什麼樣的數據? – 2012-03-20 20:46:35

+0

您不能在SQL WHERE子句中執行PL/SQL賦值語句。 – GriffeyDog 2012-03-20 21:20:26

回答

3

您不需要在WHERE子句中設置任何變量,實際上即使您不能這樣做。 你想要做的是編寫描述你想獲得的行的正確的邏輯謂詞(這是一個返回true或false的表達式)。

這裏有兩個例子來說明如何我會嘗試將其定義(據我理解你的要求):

  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. 與CASE:

    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 2012-03-21 13:26:49

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

我爲什麼要考慮使用輔助日曆表?

日曆表可以更容易地圍繞 圍繞任何涉及日期的商業模式開發解決方案。最後我檢查了一下,這個 涵蓋了幾乎所有你能想到的商業模式,還有一些 的學位。這最終需要冗長恆問題, 複雜和低效的方法包括以下幾個問題:X和Y之間

  • 多少個工作日?

  • 3月的第二個星期二到4月的第一個星期五之間的日期是什麼?

  • ...

...也許a column for julianized business days