我有一个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)。由于这将在记录中计算,我不确定如何编写。
答案 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'