用于显示工作人员工作小时数的SQL过程

时间:2017-12-04 20:02:19

标签: sql oracle plsql

+-----------+-------------------------------+-------+
| 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参数的程序,它会显示当天工人工作了多少小时和分钟。谢谢你的帮助。

3 个答案:

答案 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的变量。