输入表:
store | employee | date | timein | timeout |
1 | A | 1-jan-12 | 10:00 | 17:00 |
1 | A | 1-jan-12 | 20:00 | 22:00 |
2 | B | 1-jan-12 | 10:00 | - |
2 | B | 1-jan-12 | 17:00 | 20:00 |
2 | B | 2-jan-12 | 10:00 | 17:00 |
3 | C | 1-jan-12 | 10:00 | 12:00 |
3 | C | 1-jan-12 | 13:00 | 15:00 |
3 | C | 1-jan-12 | 20:00 | 23:00 |
所需的输出:
store | employee | date | timein | timeout | hours | working_days |
1 | A | 1-jan-12 | 10:00 | 17:00 | 7 | |
1 | A | 1-jan-12 | 20:00 | 22:00 | 2 | 1 |
2 | B | 1-jan-12 | 10:00 | - | 0 | |
2 | B | 1-jan-12 | 17:00 | 20:00 | 5 | 0 |
2 | B | 2-jan-12 | 10:00 | 17:00 | 7 | 1 |
3 | C | 1-jan-12 | 10:00 | 12:00 | 2 | |
3 | C | 1-jan-12 | 13:00 | 15:00 | 2 | |
3 | C | 1-jan-12 | 20:00 | 23:00 | 3 | 1 |
我的查询是:
select
store,
employee,
date,
timein,
timeout,
cast(trim(trailing ':' from cast(timeout) as number)-trim(trailing ':' from cast(timein) as number) as number) as hours,
case
when timeout is null then 0 and
end
from
tableattend
where date between '1-jan-12' and '2-jan-12' and store between 'A' and 'C'
working_days 字段将以这种方式显示,但无法获得创建上述结果的确切功能。请指导我。
答案 0 :(得分:0)
您在提交中声明了生成WORKING_DAYS的规则:
这是查询的简化版本,解决了具体问题:
select date
, timein
, timeout
, case
when rn != 1 then null
when timeout is null then 0
else 1
end as working_days
from ( select date
, timein
, timeout
, row_number() over partition by date order by timein desc ) rn
from tableattend
where date between '1-jan-12' and '2-jan-12'
and store between 'A' and 'C' )
order by date, timein
答案 1 :(得分:0)
APC的回答略有不同,因为我对工作日规则的解释略有不同......这给出了您的预期输出。但似乎不符合你所说的规则:
select store, employee, dt, timein, timeout, hours,
case when rn = 1 then decode(tmp_timeout, null, 0, 1) end as working_days
from (
select store, employee, dt, timein, timeout,
case when timeout is null then 0
else extract (hour from to_dsinterval('0 ' || timeout || ':00')
- to_dsinterval('0 ' || timein || ':00'))
end as hours,
first_value(timeout)
over (partition by store, employee, dt
order by timeout nulls first) as tmp_timeout,
row_number()
over (partition by store, employee, dt
order by timein desc) as rn
from tableattend
)
where dt between '1-jan-12' and '2-jan-12'
-- and store between 'A' and 'C' -- store is numeric??
/
我调用日期列dt
来避免使用保留字,但尝试匹配您提供的字。
STORE EMPLOYEE DT TIMEIN TIMEOUT HOURS WORKING_DAYS
---------- -------- --------- ------ ------- ---------- ------------
1 A 01-JAN-12 10:00 17:00 7
1 A 01-JAN-12 20:00 22:00 2 1
2 B 01-JAN-12 10:00 0
2 B 01-JAN-12 17:00 20:00 3 0
2 B 02-JAN-12 10:00 17:00 7 1
3 C 01-JAN-12 10:00 12:00 2
3 C 01-JAN-12 13:00 15:00 2
3 C 01-JAN-12 20:00 23:00 3 1
如果您将时间作为完整日期存储而不是作为单独的(varchar2)列存储,则会更容易。目前尚不清楚如果有人在午夜过夜会发生什么或应该发生什么,所以timeout
似乎会出现在timein
之前。
答案 2 :(得分:0)
关于如何减去时间部分以获得小时的几个例子,如上例所示。不清楚你是如何得到工作日的。我认为您可以将工作时间除以8以获得工作日...所有示例都经过测试:
SELECT round((time_diff/3600)/24, 1) days
, trunc(time_diff/3600) hrs
, trunc(mod(time_diff, 3600) / 60) mnt
, trunc(mod(time_diff, 3600) / 60 /60) sec
FROM
(
SELECT time_in, time_out, (time_out-time_in)* 86400 time_diff
FROM
(
SELECT to_date('01-JAN-2012 17:00:00', 'DD-MON-YYYY HH24:MI:SS') time_out
, to_date('01-JAN-2012 10:00:00', 'DD-MON-YYYY HH24:MI:SS') time_in
FROM dual
))
/
使用提取示例:
Select time_in, time_out, time_diff,
EXTRACT(DAY FROM time_diff) days,
EXTRACT(HOUR FROM time_diff) hours,
EXTRACT(MINUTE FROM time_diff) minutes,
EXTRACT(SECOND FROM time_diff) seconds
From
(
Select time_in, time_out, (time_out - time_in) time_diff
From
(
Select CAST(to_date('01-JAN-2012 17:00:00', 'DD-MON-YYYY HH24:MI:SS') AS TIMESTAMP) time_out
, CAST(to_date('01-JAN-2012 10:00:00', 'DD-MON-YYYY HH24:MI:SS') AS TIMESTAMP) time_in
From dual
))
/