2012-03-20 41 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