Oracle SQL-根据签入和签出记录获取日期之间的差异
假设我有下表数据Oracle SQL-根据签入和签出记录获取日期之间的差异,sql,oracle,Sql,Oracle,假设我有下表数据 # | USER | Entrance | Transaction Date Time ----------------------------------------------- 1 | ALEX | INBOUND | 2020-01-01 10:20:00 2 | ALEX | OUTBOUND | 2020-01-02 10:00:00 3 | ALEX | INBOUND | 2020-01-04 11:30:00
# | USER | Entrance | Transaction Date Time
-----------------------------------------------
1 | ALEX | INBOUND | 2020-01-01 10:20:00
2 | ALEX | OUTBOUND | 2020-01-02 10:00:00
3 | ALEX | INBOUND | 2020-01-04 11:30:00
4 | ALEX | OUTBOUND | 2020-01-07 15:00:00
5 | BEN | INBOUND | 2020-01-08 08:00:00
6 | BEN | OUTBOUND | 2020-01-09 09:00:00
我想知道用户在外逗留的总天数
对于每次入境和出境视为一次行程,超过24小时的每次行程视为2天
下面是我想要的输出:
No. of Days | Trips Count
----------------------------------
Stay < 1 day | 1
Stay 1 day | 1
Stay 2 days | 0
Stay 3 days | 0
Stay 4 days | 1
我仍然不知道你说的<1天是什么意思,但我已经走了这么远 设置 质疑 结果 您可以使用select max替换6,并重复第二个子查询我将使用lead和aggregation。假设行正确交错:
select floor( (next_dt - dt) ) as num_days, count(*)
from (select t.*,
lead(dt) over (partition by user order by dt) as next_dt
from trips t
) t
where entrance = 'INBOUND'
group by floor( (next_dt - dt) )
order by num_days;
注意:这不包括0行。这似乎不是你问题的核心,是一个重要的复杂问题。到目前为止你尝试过什么?旅行<1天是什么?@user9601310我试图在一张纸上想象它,但我不知道如何构造查询。@Turo trip<1天意味着停留时间少于24小时。2天意味着旅行>24小时,1天正好是24小时?在本例中,您将旅行1分为1天。经过一番思考后,我的猜测是:入境日=出境日?谢谢你的回答,我从中得到了启发。谢谢你的回答,但我认为这将是密集的,因为我的表将非常大。有了正确的索引,这不会那么糟糕,但我自己投票支持@Gordon的答案
select decode (t.days, 0 , 'Stay < 1 day', 1, 'Stay 1 day', 'Stay ' || t.days || ' days') Days , count(d.days) Trips_count
FROM (Select Rownum - 1 days From dual Connect By Rownum <= 6) t left join
(select extract (day from b.ts - a.ts) + 1 as days from trips a
inner join trips b on a.name = b.name
and a.entrance = 'INBOUND'
and b.entrance = 'OUTBOUND'
and a.ts < b.ts
and not exists (select ts from trips where entrance = 'OUTBOUND' and ts > a.ts and ts < b.ts)) d
on t.days = d.days
group by t.days order by t.days
DAYS | TRIPS_COUNT
----------------|------------
Stay < 1 day | 0
Stay 1 day | 2
Stay 2 days | 0
Stay 3 days | 0
Stay 4 days | 1
Stay 5 days | 0
select floor( (next_dt - dt) ) as num_days, count(*)
from (select t.*,
lead(dt) over (partition by user order by dt) as next_dt
from trips t
) t
where entrance = 'INBOUND'
group by floor( (next_dt - dt) )
order by num_days;