我想加入两张桌子。一个是记录表,记录特定时间的事件。另一个是会话表。我想知道在哪个会话中发生了哪个事件。
事件表的timestamp
字段类型为timestamp(0) without time zone
,会话表的logintime
和logouttime
类型为timestamp without time zone
({{1}这是两个表中都有的字段。)
我试过的SQL是:
userid
当用户注销时,会话就可以了,但当 select S.sessionid from event E
left join session S
ON S.logintime =
(
select MAX(logintime) max
from session
where (
(logintime < E.timestamp and logouttime > E.timestamp) OR
(logintime < E.timestamp AND logouttime is null)
) and S.userid=E.userid
)
为logouttime
时,加入失败,我没有NULL
。当我手动执行所有子查询时,它们似乎产生了正确的结果。
后者的例子:
首先,我们采取随机事件记录。
sessionid
其次,我们采用join子句,用接收到的数据填充
select * from event limit 1;
timestamp | userid | ....
---------------------+--------+-----
2014-07-15 15:44:24 | 195 | ....
最后,我们采用与该时间匹配的sessionid。
select MAX(logintime) max from session
where ((logintime <'2014-07-15 15:44:24' and logouttime > '2014-07-15 15:44:24') OR
(logintime < '2014-07-15 15:44:24' AND logouttime is null)) and userid=195;
max
----------------------------
2014-07-15 12:18:03.648875
答案 0 :(得分:0)
如果您使用的是PostgreSQL 9.2+,则可以使用时间戳范围tsrange
来检测containment:
select s.sessionid
from event e
left join session s on s.userid = e.userid
and tsrange(logintime, logouttime) @> E.timestamp
注意:范围可以是unbounded,因此您无需为logouttime IS NULL
指定其他案例。
修改:如果一个用户可以在特定时间拥有多个会话(并且您只想选择具有最后一个logintime
的会话),则可以使用{{3} }子句:
select distinct on(s.sessionid) s.sessionid
from event e
left join session s on s.userid = e.userid
and tsrange(logintime, logouttime) @> E.timestamp
order by s.sessionid, logintime desc