2013-03-26 19 views
0

我有一个包含类似于以下数据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 
     . 
     . 

状态代表入住和退房,其中ID表示的个体。

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

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

回答

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' 

试试这几天对于In和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' 
+0

完美并迅速回答。我非常喜欢这些学习新技术的机会。我总是忘记命名连接。谢谢! – McArthey 2013-03-26 17:51:15

+0

如果这远远超出原始问题的范围,请让我知道,但是是否也可以计算总时间OUT?这是否需要额外的查询? – McArthey 2013-03-26 18:04:16

+0

@McArthey,检查更新的答案 – 2013-03-26 18:05:31

相关问题