自加入 table,同时保持行的顺序

Self joining a table while maintaining the order of the rows

所以我有一个 table 可以记录使用某些应用程序的用户。它具有以下字段

id
time
app
user
server
type (can be IN or OUT)

所以用户开始使用某个应用程序,当他们获得使用该应用程序的权利时,会记录一行并将类型列设置为 'OUT'

同样,当他们停止使用该应用程序时,会记录另一行,现在类型列设置为 'IN'

所以我必须建立一个会话 table,它显示某个用户和服务器使用应用程序到用户停止使用它之间的时间。

所以我进行了以下查询,对 table

进行了自连接
SELECT A.time as OutTime, B.time as InTime, A.app, 
A.username, A.requestserver
FROM logs A, logs B
WHERE A.app = B.app
AND A.username = B.username
AND A.requestserver = B.requestserver
AND A.type = 'OUT'
AND B.type = 'IN'
AND A.time < B.time

我不确定这个100%的逻辑是否正确。如果存在来自同一服务器的同一用户有两个会话的情况,例如:

结束 (1) -> 上午 10 点

在 (1) -> 下午 1 点

结束 (2) -> 下午 3 点

在 (2) -> 晚上 7 点

现在按照我的逻辑,我有可能只创建一个从上午 10 点到晚上 7 点的会话,这是错误的。我该怎么做?

我会用 window 函数而不是 self-join 来做这件事。您可以将 window 设置为仅当前行之前的行,如果有兴趣,还可以出于性能原因设置最大会话长度。

假设您的 time 字段是一个完整的时间戳,而不仅仅是一天中的时间:

with sessionized as (

select
    *,
    last_value(
        case when type = 'IN' then time end
        ignore nulls
    ) over (
        partition by username, app, requestserver
        order by time asc
        rows between unbounded preceding and current row
    ) as session_start

from logs

)
select *
from sessionized 
where type = 'OUT'