1

我有一个复杂的域结构:

User:        id, name, email
Team:        id, name
UserTeam:    id, user_id, team_id
Session:     id, data
UserSession: id, user_id, session_id
TeamSession: id, team_id, session_id
Scan:        id, user_id, session_id, test_data

我可以邀请用户参加“会议”。用户可以进行会话(创建一个UserSession),如果完成,结果将存储在Scan. 我还可以邀请一个完整的团队,这样TeamSession就创建了一个,并且为每个团队成员UserSession制作了一个。

现在我想执行查询:给我所有尚未执行的扫描(这样我就可以记住用户进行一次)。对于这种情况,我想选择所有用户会话并加入扫描id 所在的扫描NULL。我认为这是从连接表中找出一行的方法还没有出现。

这是我的查询:

SELECT us.id as userSessionId,
       sc.id as scanId,
       s.id as sessionId,
       u.id, u.name

FROM usersessions us
     LEFT JOIN sessions s ON us.session_id = s.id
     LEFT JOIN scans sc   ON us.session_id = sc.session_id
     LEFT JOIN users u    ON us.user_id = u.id

WHERE sc.id IS NULL

GROUP BY us.id

但是,它不起作用:当至少有一个用户尚未执行扫描时,没有返回任何内容。如果我删除该WHERE子句以查看数据是什么,我会得到这个:

userSessionId  scanId  sessionId  id  name
45             45      39         39  John
46             45      39         40  Jane
47             45      39         41  Tom
48             45      39         42  Mark

在这种情况下,所有人都在同一个组中并获得了一个会话(#39)。他们的用户 ID 和用户会话 ID 是正确的。Mark 没有进行扫描。约翰确实扫描了#45(对于简来说是#46,汤姆是#47)。

如果我添加 where 子句WHERE sc.user_id=u.id,我会得到正确的三个结果(扫描 #45、#46 和 #47),但是 Mark 丢失了。那是我最后想要抓住的唯一一个!如果您将其更改为两个子句WHERE sc.user_id=u.id AND sc.id IS NULL,则它(显然现在)不再返回任何内容。

获取所有未连接到扫描的用户会话的查询是什么?

4

2 回答 2

1

消除GROUP BY查询中的子句。如果没有 Aggregate 函数,它是无效的,但是在 MySQL 中,它不会抛出错误并且会返回“随机”行。用于ORDER BY对答案进行排序。

SELECT us.id as userSessionId,
       sc.id as scanId,
       s.id as sessionId,
       u.id, u.name

FROM usersessions us
     LEFT JOIN sessions s ON us.session_id = s.id
     LEFT JOIN users u    ON us.user_id = u.id

WHERE us.session_id IS NULL

ORDER BY us.id
于 2012-07-13T21:57:39.453 回答
1

你可以试试这个解决方案。如果它适合您,我将编辑我的帖子以添加解释:

SELECT
    a.id AS userSessionId,
    b.id AS scanId,
    a.session_id AS sessionId,
    a.user_id,
    c.name
FROM
(
    SELECT a.*
    FROM usersessions a
    LEFT JOIN scans b ON a.user_id = b.user_id AND a.session_id = b.session_id
    WHERE b.id IS NULL
) a
INNER JOIN
(
    SELECT id, session_id
    FROM scans
    GROUP BY id, session_id
) b ON a.session_id = b.session_id
INNER JOIN
    users c ON a.user_id = c.id

我假设您的数据看起来像这样:

usersessions:
id  |  uid  |  session_id
-------------------------
45  |   39  |   39
46  |   40  |   39
47  |   41  |   39
48  |   42  |   39


scans:
id  |  uid  |  session_id
-------------------------
45  |  39   |  39
45  |  40   |  39
45  |  41   |  39

在这种情况下,您应该最终得到:

userSessionId  |  scanId  |  sessionId  |  user_id  |  name
-----------------------------------------------------------
48             |  45      |  39         |  42       |  Mark

让我知道您的扫描表是否允许看起来像:

scans:
id  |  uid  |  session_id
-------------------------
45  |  39   |  39
45  |  40   |  39
45  |  41   |  39
46  |  39   |  39
46  |  40   |  39
46  |  41   |  39
46  |  42   |  39

^ 在这种情况下,我的查询将不起作用,并且需要重写(我知道如何)。

于 2012-07-13T22:30:29.710 回答