我有三个表:用户,会话和usersessions。 users-table包含系统中所有用户的列表,sessions表是所有当前Web客户端会话的列表,usersessions是一个表,用于跟踪哪些会话具有用户登录。
注意sessions.id(主键整数)和sessid(本质上是HTTP cookie)之间的区别。
CREATE TABLE users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL UNIQUE,
passwd TEXT NOT NULL
);
CREATE TABLE sessions (
id INTEGER PRIMARY KEY,
sessid TEXT UNIQUE NOT NULL,
last_access DATETIME NOT NULL DEFAULT current_timestamp,
ip TEXT NOT NULL
);
CREATE TABLE usersessions (
id INTEGER PRIMARY KEY,
sess_id INTEGER UNIQUE NOT NULL,
user_id INTEGER NOT NULL,
FOREIGN KEY(sess_id) REFERENCES sessions(id),
FOREIGN KEY(user_id) REFERENCES users(id),
UNIQUE(sess_id, user_id)
);
我使用以下测试数据:
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和名称(如果有的话。)
我找到了类似问题的大量答案,但这些问题往往只涉及两个表格;即喜欢:
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
这原则上是我想要的信息; user_id中sess_id = 1的NULL告诉我会话2不是登录会话。但是,我想要的是获取登录会话的用户名(否则为NULL);即我想要结果:
sess_id user_id user ip
---------- ---------- ------ ------------
1 2 elena 172.16.0.128
2 10.0.0.1
由于NULL(us.user_id!= u.id),我提出的查询总是最终过滤掉非登录会话。
我通过做两个查询简单地解决了这个问题,但我的问题是,如果可以在一个查询中完成此操作?我本质上想要设置"用户"列(从概念上讲)"来自用户表的列为u.id = us.user_id,如果没有匹配,则为NULL"。
我知道还有其他完全不同的解决方案,比如合并表usersessions和session,以便user_id在会话中是NULL:able列,或者只是进行两次查询等(这些方法正是我所做的那样)这些年来一直在使用以解决类似情况,但我特别想知道是否有一种方法,使用上面指定的表配置来检查会话是否有效,如果是登录会话(如果是,则获取用户名),在一个查询中?
答案 0 :(得分:0)
您可以链接左外连接:
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
这将为每个没有user_sessions.user_id值的用户表记录获取空值