我正在编写一个查询,让我可以查看特定工作需要完成的锻炼日期。
以下是我的工作和代码列表。
JOB_NO | CODES | RCVD_TIME
ABC1 | 1 | 07-JAN-17 09:44:07
DEF2 | 3 | 20-MAR-17 14:32:49
GHI3 | 3 | 27-MAR-17 10:00:03
JKL4 | 1 | 12-JAN-17 12:59:05
现在我有一些条件来训练这些工作的结束日期/时间。
代码1 - 在23:59:59之前添加1天+任意时间 代码3 - 如果rcvd时间在下午1点之前,那么工作将在同一天完成,直到23:59:59,如果rcvd时间是下午1点,或者之后工作将在第二天下午1点之前完成。
我的简单查询:
SELECT
JOB_NO, CODES, RCVD_TIME,
CASE
WHEN CODES = '1'
THEN RCVD_TIME + 1
ELSE RCVD_TIME
END AS TARGET
FROM...
这给了我(不知道如何为代码3编写查询):
JOB_NO | CODES | RCVD_TIME | TARGET
ABC1 | 1 | 07-JAN-17 09:44:07 | 08-JAN-17 09:44:07
DEF2 | 3 | 20-MAR-17 14:32:49 | 20-MAR-17 14:32:49
GHI3 | 3 | 27-MAR-17 10:00:03 | 27-MAR-17 10:00:03
JKL4 | 1 | 12-JAN-17 12:59:05 | 13-JAN-17 12:59:05
这就是我想要的:
JOB_NO | CODES | RCVD_TIME | TARGET
ABC1 | 1 | 07-JAN-17 09:44:07 | 08-JAN-17 23:59:59
DEF2 | 3 | 20-MAR-17 14:32:49 | 21-MAR-17 13:00:00
GHI3 | 3 | 27-MAR-17 10:00:03 | 27-MAR-17 23:59:59
JKL4 | 1 | 12-JAN-17 12:59:05 | 13-JAN-17 23:59:59
如果有人可以就如何得到我所要求的答案提出建议,我真的很感激。
提前致谢。
修改
有点令人沮丧,但被告知要再增加一个条件,考虑一周的工作日是在1到6之间,所以必须确保目标时间不会进入星期日(第7天)。对不起双人的家伙,只是想我会在这里添加它,以防万一丢失。答案 0 :(得分:0)
您可以在SQL中使用CASE
语句来处理复杂的if-then逻辑。
-- TEST_DATA is not part of the solution
with test_data ( job_no, code, rcvd_time, target ) AS (
SELECT 'ABC1',1,to_date('07-JAN-17 09:44:07','DD-MON-YY HH24:MI:SS'),to_date('08-JAN-17 09:44:07','DD-MON-YY HH24:MI:SS') FROM DUAL UNION ALL
SELECT 'DEF2',3,to_date('20-MAR-17 14:32:49','DD-MON-YY HH24:MI:SS'),to_date('20-MAR-17 14:32:49','DD-MON-YY HH24:MI:SS') FROM DUAL UNION ALL
SELECT 'GHI3',3,to_date('27-MAR-17 10:00:03','DD-MON-YY HH24:MI:SS'),to_date('27-MAR-17 10:00:03','DD-MON-YY HH24:MI:SS') FROM DUAL UNION ALL
SELECT 'JKL4',1,to_date('12-JAN-17 12:59:05','DD-MON-YY HH24:MI:SS'),to_date('13-JAN-17 12:59:05','DD-MON-YY HH24:MI:SS') FROM DUAL)
-- Actual solution begins here...
SELECT job_no, code, rcvd_time,
case
when rcvd_time - trunc(rcvd_time) < 13/24 and code = 1 then
trunc(rcvd_time) + (86399/86400) + 1
when rcvd_time - trunc(rcvd_time) < 13/24 and code = 3 then
trunc(rcvd_time) + (86399/86400)
when rcvd_time - trunc(rcvd_time) >= 13/24 then
trunc(rcvd_time) + 1 + (13/24)
end target
from test_data;
答案 1 :(得分:0)
您可以使用区间文字(因此您不需要在代码中撒上幻数):
CASE
WHEN code = 1
THEN TRUNC( rcvd_time ) + INTERVAL '2' DAY - INTERVAL '1' SECOND
WHEN code = 3 AND TO_CHAR( rcvd_time, 'HH24' ) < '13'
THEN TRUNC( rcvd_time ) + INTERVAL '1' DAY - INTERVAL '1' SECOND
WHEN code = 3 -- AND TO_CHAR( rcvd_time, 'HH24' ) >= '13'
THEN TRUNC( rcvd_time ) + INTERVAL '1' DAY + INTERVAL '13' HOUR
END
比较您可以使用各种不同技术的时间:
TO_CHAR( rcvd_time, 'HH24' ) < '13'
EXTRACT( HOUR FROM CAST( rcvd_time AS TIMESTAMP ) ) < 13
rcvd_time < TRUNC( rcvd_time ) + INTERVAL '13' HOUR
答案 2 :(得分:0)
在下面的解决方案中,我假设&#34;特殊&#34;处理仅在CODES
为3时适用,否则TARGET
是第二天的结束。 (这允许除了1和3之外的CODES
值...如果您有更多CODES
值和其他规则,则可以进行调整。)
由于所有TARGET
日期时间都偏离trunc(rcvd_time)
,因此我只使用CASE
表达式来确定偏移量。
select job_no, codes, rcvd_time,
trunc(rcvd_time) +
case codes when 3 then
case when extract (hour from cast (rcvd_time as timestamp)) < 13
then interval '23:59:59' hour to second
else interval '1 13:00:00' day to second
end
else interval '1 23:59:59' day to second
end as target
from your_table;
注意:感谢MT0显示从日期中提取小时的方法;我忘记了extract(hour from...)
仅适用于时间戳。我相应地编辑了我的答案。
答案 3 :(得分:0)
试试这个
select
t.*
,case when codes=3
and to_date(to_char(rcvd_time,'HH24:MI:SS'),'HH24:MI:SS')
>=to_date('13:00:00','HH24:MI:SS')
then trunc(rcvd_time)+1+(13/24) -- add 1 day and then add 13 hours
when codes=1
then trunc(rcvd_time)+2-(1/(24*60*60)) --add 2 days and subtract 1 second
else
trunc(rcvd_time)+1-(1/(24*60*60)) -- add 1 day and subtract 1 second
end as target
from tbl t;
工作样本
with tbl (JOB_NO,CODES,RCVD_TIME) as (
select 'ABC1',1,to_date('07-JAN-17 09:44:07','DD-MON-YY HH24:MI:SS') from dual union all
select 'DEF2',3,to_date('20-MAR-17 14:32:49','DD-MON-YY HH24:MI:SS') from dual union all
select 'GHI3',3,to_date('27-MAR-17 10:00:03','DD-MON-YY HH24:MI:SS') from dual union all
select 'JKL4',1,to_date('12-JAN-17 12:59:05','DD-MON-YY HH24:MI:SS') from dual)
select
t.*
,case when codes=3
and to_date(to_char(rcvd_time,'HH24:MI:SS'),'HH24:MI:SS')
>=to_date('13:00:00','HH24:MI:SS')
then trunc(rcvd_time)+1+(13/24) -- add 1 day and then add 13 hours
when codes=1
then trunc(rcvd_time)+2-(1/(24*60*60)) --add 2 days and subtract 1 second
else
trunc(rcvd_timeJOB_NO,CODES,RCVD_TIME)+1-(1/(24*60*60)) -- add 1 day and subtract 1 second
end as target
from tbl t;
输出
JOB_NO CODES RCVD_TIME TARGET
ABC1 1 07-JAN-2017 09:44:07 08-JAN-2017 23:59:59
DEF2 3 20-MAR-2017 14:32:49 21-MAR-2017 13:00:00
GHI3 3 27-MAR-2017 10:00:03 27-MAR-2017 23:59:59
JKL4 1 12-JAN-2017 12:59:05 13-JAN-2017 23:59:59