0

我有一个包含类似于以下数据的 Oracle 表:

身份证 | 状态 | 时间
-------------------------------------------
 1 | 输入 | 2013/26/03 00:00
 1 | 输出 | 2013/26/03 07:00
 1 | 输入 | 2013/27/03 03:00
 2 | 输入 | 2013/26/03 01:00
 2 | 输出 | 2013/26/03 06:00
 3 | 输入 | 2013/26/03 01:30
        .
        .

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

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

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

4

1 回答 1

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'
于 2013-03-26T17:39:17.950 回答