Sql 具有额外间接级别的单个左连接查询

Sql 具有额外间接级别的单个左连接查询,sql,sqlite,join,Sql,Sqlite,Join,我有三个表:users、sessions和usersessions。users表包含系统中所有用户的列表,sessions表是所有当前web客户端会话的列表,usersessions表跟踪哪些会话具有用户登录 注意sessions.id(主键整数)和sessiond(本质上是HTTP cookie)之间的区别 我使用以下测试数据: users: id name passwd ----------

我有三个表:users、sessions和usersessions。users表包含系统中所有用户的列表,sessions表是所有当前web客户端会话的列表,usersessions表跟踪哪些会话具有用户登录

注意sessions.id(主键整数)和sessiond(本质上是HTTP cookie)之间的区别

我使用以下测试数据:

users:
id          name        passwd                                  
----------  ----------  ----------------------------------------
1           frank       8843d7f92416211de9ebb963ff4ce28125932878
2           elena       8843d7f92416211de9ebb963ff4ce28125932878
3           drake       8843d7f92416211de9ebb963ff4ce28125932878

sessions:
id          sessid      last_access          ip          
----------  ----------  -------------------  ------------
1           mysess      2015-11-28 18:27:46  172.16.0.128
2           unusedsess  2015-11-28 18:27:46  10.0.0.1    

usersessions:
id          sess_id     user_id   
----------  ----------  ----------
1           1           2         
当连接到web服务器时,我想查询数据库(使用cookie中的会话id)以获取会话id(主键)以及登录的用户id和名称(如果有)

我已经找到了很多类似问题的答案,但这些问题往往只涉及两张表;i、 e.例如:

SELECT s.id AS sess_id,us.user_id AS user_id,s.ip
  FROM sessions AS s
  LEFT OUTER JOIN usersessions AS us ON us.sess_id=s.id;
这将返回:

sess_id     user_id     ip          
----------  ----------  ------------
1           2           172.16.0.128
2                       10.0.0.1    
原则上这是我想要的信息;sess_id=1的用户_id中的NULL告诉我会话2不是登录会话。但是,我想要的是还获取登录会话的用户名(否则为NULL);i、 e.我想要结果:

sess_id     user_id     user    ip          
----------  ----------  ------  ------------
1           2           elena   172.16.0.128
2                               10.0.0.1    
我提出的查询总是过滤掉非登录会话,因为它是空的(us.user_id!=u.id)

我通过两个查询解决了这个问题,但我的问题是,这是否可以在一个查询中完成?我本质上想将“user”列设置为(概念上)“name column from users table for u.id=us.user\u id,如果不匹配,则设置为NULL”


我知道还有其他完全不同的解决方案,比如合并表usersessions和sessions,以便user_id在sessions中为空:able列,或者只是进行两次查询,等等(这些方法正是我多年来一直在使用的“解决”类似情况的方法),但我特别想知道是否有办法,使用上面指定的表配置,要在一次查询中检查会话是否有效,是否是登录的会话(如果是,则获取用户名?

您可以链接左侧外部联接:

SELECT s.id AS sess_id,us.user_id AS user_id,s.ip, users.name
  FROM sessions AS s
  LEFT OUTER JOIN usersessions AS us ON us.sess_id=s.id
  LEFT OUTER JOIN users ON users.id = us.user_id

这将为没有用户会话的每个用户表记录获取空值。用户id值

这与我尝试过的方法一致,但我颠倒了两个连接的顺序。我没有想到这个订单意义重大。
SELECT s.id AS sess_id,us.user_id AS user_id,s.ip, users.name
  FROM sessions AS s
  LEFT OUTER JOIN usersessions AS us ON us.sess_id=s.id
  LEFT OUTER JOIN users ON users.id = us.user_id