Sql where子句中如何正确使用case
所以我有一个过程,我目前正在调试,我已经把它缩小到这个select语句 注:其中,截止日期(“”),33005220是参数的表示形式 现在,我们要做的是,取一个参数,它是一个时间戳,然后减去一个偏移值 偏移量是自星期日午夜=0的一周开始以来经过的分钟数。(因此,如果是周一午夜,偏移量将=1440) 当从参数中减去偏移量时,就得到了一周的开始。然后从已经预先确定的表中获取偏移量值,并将该值添加到周初以获得时间戳 这样做是为了获得班次的开始日期和结束日期 我的原始代码在下面没有问题,但是它缺少周六到周日的边界条件Sql where子句中如何正确使用case,sql,oracle,plsql,Sql,Oracle,Plsql,所以我有一个过程,我目前正在调试,我已经把它缩小到这个select语句 注:其中,截止日期(“”),33005220是参数的表示形式 现在,我们要做的是,取一个参数,它是一个时间戳,然后减去一个偏移值 偏移量是自星期日午夜=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;
选择SHIFT\u ID\u PK、SHIFT\u NAME\u FK、,
班次开始日期,班次开始时间,
班次结束日,班次结束时间,
站点ID\u FK,轮班日ID,
开始偏移,结束偏移,
将时间戳(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”)作为班次开始日期,
至时间戳(至字符((PENDTIMESTAMP-(VENDOFFSET/24/60))+(ENDOFFSET/24/60),“YYYY-MM-DD HH:MI:SS AM”),“YYYY-MM-DD HH:MI:SS AM TZM”)作为班次结束日期
从班次
哪里
ENDOFFSET>=VSTARTOFFSET
和STARTOFSET<偏移量
按班次\开始\日期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;
声明
VSTARTOFFSET整数;
偏移量整数;
shiftofset整数;
PSTARTTIMESTAMP时间戳;
时间戳;
开始
VSTARTOFFSET:=10020;
偏移量:=420;
PSTARTTIMESTAMP:=截止日期('2012年3月17日23:00','mm/dd/yyyy hh24:mi');
PENDTIMESTAMP:=截止日期('2012年3月18日7:00','mm/dd/yyyy hh24:mi');
选择SHIFT\U ID\U PK、SHIFT\U NAME\U FK、,
班次开始日期,班次开始时间,
班次结束日,班次结束时间,
站点ID\u FK,轮班日ID,
开始偏移,结束偏移,
将时间戳(TO_CHAR((PSTARTTIMESTAMP-(VSTARTOFFSET/24/60))+(STARTOFFSET/24/60)、“yyy-MM-DD HH:MI:SS AM”)、“YYYY-MM-DD HH:MI:SS AM TZH:TZM”)作为班次开始日期,
至时间戳(至字符((PENDTIMESTAMP-(VENDOFFSET/24/60))+(ENDOFFSET/24/60),“YYYY-MM-DD HH:MI:SS AM”),“YYYY-MM-DD HH:MI:SS AM TZM”)作为班次结束日期
从班次
哪里
案例
当班次开始日=7,班次结束日=1时
shiftofset:=ENDOFFSET+10080;
和VENDOFFSET:=VENDOFFSET+10080;
其他的
shiftofset:=内偏移;
结束
shiftofset>=VSTARTOFFSET
和STARTOFSET<偏移量
按班次\开始\日期asc订购;
结束;
如您所见,我不确定如何处理where子句中的case语句。基本上,我想做的是,如果开始日是星期六,结束日是星期天,那么将10080(一周)添加到结束偏移量/销售偏移量,如果不满足该条件,则使用原始值
基本上,我的问题相当简单……我相信,但我很难找到解决方案。所以我想知道的是如何在where子句中正确使用case语句。如果我不打算在where子句中使用这种形式的case语句,那么我应该如何设置这个select语句呢
非常感谢您的帮助或建议。
谢谢。与其在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;
与其尝试在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;
您不需要在WHERE子句中设置任何变量,实际上即使您不能这样做。 您要做的是编写正确的逻辑谓词(即返回true或false的表达式)来描述要获取的行 以下是我将如何定义它的两个示例(据我了解,您的需求):
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 )
在哪里
(班次开始日=7,班次结束日=1,内偏移+10080>=VSTARTOFFSET和STARTOFFSET=VSTARTOFFSET和STARTOFFSET
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)
在哪里
(班次开始日=7,班次结束日=1,则ENDOFFSET+10080,否则ENDOFFSET END)>=VSTARTOFFSET
和STARTOFSET<(班次开始日=7,班次结束日=1,则VENDOFFSET+10080,否则VENDOFFSET结束)
我没有调试此表达式,因此不希望它们工作;),但是我希望您已经有了这个想法。您不需要在WHERE子句中设置任何变量,实际上即使您不能这样做。 您要做的是编写正确的逻辑谓词(即返回true或false的表达式)来描述要获取的行 以下是我将如何定义它的两个示例(据我了解,您的需求):
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 )
在哪里
(班次开始日=7,班次结束日=1,内偏移+10080>=VSTARTOFFSET和STARTOFFSET