+-----------+-------------------------------+-------+
| Worker ID | Time(MM/DD/YYYY Hour:Min:Sec) | InOut |
+-----------+-------------------------------+-------+
| 1 | 12/04/2017 10:00:00 | In |
| 2 | 12/04/2017 10:00:00 | In |
| 2 | 12/04/2017 18:40:02 | Out |
| 3 | 12/04/2017 10:00:00 | In |
| 1 | 12/04/2017 12:01:00 | Out |
| 3 | 12/04/2017 19:40:05 | Out |
+-----------+-------------------------------+-------+
嗨!我的项目有问题,我觉得有些人会帮助我。我有这样的表。这是一个简单的表格,表明工人进出公司。我需要做一个将ID和日期作为In参数的程序,它会显示当天工人工作了多少小时和分钟。谢谢你的帮助。
答案 0 :(得分:0)
是的,在我以前的工作中,我不得不做这样的一些查询。以下是我使用的方法,效果非常好:
每个" Out"记录,得到MAX(TIME)on" In"时间早于的记录比OUT记录
这有意义吗?你基本上是自己加入桌子,寻找代表"时钟的记录。任何特定的时间"时钟输出"时间。
所以这是主干:
select
*
, (
SELECT MAX(tim) from @tempTable subQ
where subQ.id = main.id
and subQ.tim <= main.tim
and subQ.InOut = 'In'
) as correspondingInTime
from @tempTable main
where InOut = 'Out'
...从这里,您可以获得所需的数据。通过操纵上面的查询,或者将其用作子查询本身(这是我最喜欢的方式) - 类似于:
select id as workerID, sum(DATEDIFF(s, correspondingInTime, tim)) as totalSecondsWorked
from
(
select
*
, (
SELECT MAX(tim) from @tempTable subQ
where subQ.id = main.id
and subQ.tim <= main.tim
and subQ.InOut = 'In'
) correspondingInTime
from @tempTable main
where InOut = 'Out'
) mainQuery
group by id
编辑:删除&#39; as&#39;在对应时间之前,因为oracle不允许&#39;作为&#39;在表别名中。
答案 1 :(得分:0)
我相当确定Oracle允许您最近使用CROSS APPLY
。
SELECT [Worker ID], yt.Time - ca.Time
FROM YourTable yt
CROSS APPLY (SELECT MAX(Time) AS Time
FROM YourTable
WHERE [Worker ID] = yt.[Worker ID] AND Time < yt.Time AND InOut = 'In') ca
WHERE yt.InOut = 'Out'
答案 2 :(得分:0)
也许类似于
select sum( time1 - prev_time1 ) from (
select InOut, time1,
prev(time1) over (partition by worker_id order by time1) prev_time1,
prev(InOut) over (partition by worker_id order by time1) prev_inOut
from MyTABLE
where TimeColumn between trunc(:date1) and trunc( :date1 + 1 )
and workerId = :workerId
) t1
where InOut = 'Out' and prev_InOut = 'In'
会去的。 :workerId和:date1是根据需要约束到一个日期和一个worker的变量。