查询根据单独的状态字段在同一字段上执行日期算术运算?

时间:2013-03-26 17:36:02

标签: oracle11g

我有一个Oracle表,其中包含类似于以下内容的数据:

ID | STATUS |      TIME
-------------------------------
 1 |   IN   |  2013/26/03 00:00
 1 |   OUT  |  2013/26/03 07:00
 1 |   IN   |  2013/27/03 03:00
 2 |   IN   |  2013/26/03 01:00
 2 |   OUT  |  2013/26/03 06:00
 3 |   IN   |  2013/26/03 01:30
        .
        .

STATUS表示签到和签出,其中ID代表个人。

我使用子查询提出了一个查询,但它似乎不优雅且效率低下。是否可以编写单个查询(意味着没有子查询)来计算每个ID的经过时间(IN - > OUT)?

更新:此外,是否可以显示个人OUT的经过时间?例如,在上面列出的数据中,个人#1是IN 7小时,但OUT 20小时(2013/27/03 03:00 - 2013/26/03 07:00)。由于这将在记录中计算,我不确定如何编写。

1 个答案:

答案 0 :(得分:2)

试试这个

select timein.id, 24 * (timeout.time - timein.time) ElapsedTime
from t timein 
left outer join t timeout on timein.id = timeout.id
where timein.status = 'IN' and timeout.status = 'OUT'

如果你的时间字段是char数据类型,那么你需要这样做

select timein.id, 24 * (TO_DATE(timeout.time, 'YYYY-DD-MM hh24:mi') 
                      - TO_DATE(timein.time, 'YYYY-DD-MM hh24:mi')) ElapsedTime
from t timein 
left outer join t timeout on timein.id = timeout.id
where timein.status = 'IN' and timeout.status = 'OUT'

尝试这几天的时间

select timein.id, NUMTODSINTERVAL((timeout.time - timein.time),'day') ElapsedTime
from t timein 
left outer join t timeout on timein.id = timeout.id
where timein.status = 'IN' and timeout.status = 'OUT'

对于进出时间,您可以使用此功能并根据您的数据进行修改

with cte as
(
select t.id, status,
24 * (t.time - LAG(t.time) 
  OVER (partition by id ORDER BY t.time)) AS diff
from t
)
select t1.id, t1.diff timeIn, t2.diff timeOut
from cte t1
LEFT OUTER JOIN
cte t2 on t1.id = t2.id  and t2.status = 'IN' and t2.diff is not null
where t1.status = 'OUT'