我陷入一个查询,我想做几件事: -我有一张桌子,上面有一些事件,每个事件的人数都有限 -在其他表格中,我记录了谁申请了哪个活动 -在网站上,我只想向用户显示他可以应用的事件(更确切地说,他尚未应用的事件;一旦他应用,则该事件将不再对用户可见)和/或应用的人数少于max_no_people(活动满时,无需向用户显示
我在另一个线程中从这里获得了帮助,但这只是部分问题。 表格如下:
other_events (eventID, max_no_people, active)
event_applied (eventID, userID)
以下是查询:
SELECT count(event_applied.eventid) AS no_applied,
e.eventID, e.max_no_people, e.active
FROM other_events e
INNER JOIN
event_applied ON event_applied.eventID = e.eventID
LEFT JOIN
event_applied ea ON ea.eventID
AND event_applied.userID = :userID
WHERE ea.eventID IS NULL
AND e.active = 1
GROUP BY event_applied.eventID
HAVING (no_applied < max_no_people)
此查询对当前选择的用户以外的其他用户都有效-但-对其他用户而言。 假设您有 userID = 42 (不在与eventID = 123配对的events_applied表中):
other_events
eventID | max_no_people | active
--------|---------------|-------
21 | 5 | 1
和在events_applied
中eventID | userID
--------|-------
123 | 10
123 | 11
123 | 12
123 | 13
123 | 14
查询将返回空行(因为事件已满,并且您无法再应用),但是如果您是 userID = 12 (位于events_applied表中且具有eventID对),则结果将如下所示:
no_applied | e.eventID | e.max_no_people | e.active
-----------|-----------|-----------------|---------
**4** | 123 | 5 | 1
因此,该事件将可见,您将能够一次又一次地申请(我知道我必须添加一些其他控件,但稍后再解决)。
因此,问题在于该查询以某种方式丢弃了当前用户的行,并且没有将其添加到最终计数中。
有人吗? :)
答案 0 :(得分:0)
问题在于,在当前查询中,您仅明确排除了用户已应用的条目,因此该计数减少了一个。相反,您需要排除所有应用了事件的事件。
由于使用的是LEFT JOIN,因此需要使用子查询来选择所有这些事件,然后仅加入事件(而不加入用户)。
SELECT count(event_applied.eventid) AS no_applied, e.eventID, e.max_no_people, e.active
FROM other_events e
INNER JOIN event_applied ON event_applied.eventID = e.eventID
LEFT JOIN (SELECT * FROM event_applied WHERE event_applied.userID = :userID ) ea
ON ea.eventID = e.eventID
WHERE ea.eventID IS NULL AND e.active = 1
GROUP BY e.eventID, e.max_no_people, e.active
HAVING (no_applied < max_no_people)
答案 1 :(得分:0)
查询的主要问题是您没有关联与特定left join
上的eventID
查询。
考虑以下代码:
SELECT
COUNT(*) AS no_applied,
e.eventID,
e.max_no_people,
e.active
FROM
other_events e
INNER JOIN event_applied ea1 ON ea1.eventID = e.eventID
LEFT JOIN event_applied ea2 ON ea1.eventID = ea2.eventID AND ea2.userID = :userID
WHERE ea2.eventID IS NULL AND e.active = 1
GROUP BY e.eventID, e.max_no_people, e.active
HAVING (no_applied < e.max_no_people)
如果您使用示例数据运行此查询 in this DB Fiddle :
带有userID = 42
,它不返回任何记录:这是因为没有可用的事件(只有一个事件,该事件已经满了)
带有userID = 12
,它不返回任何记录:这是因为该用户已应用于唯一可用的事件
我建议创建一个更具代表性的数据集,例如,通过创建另一个未满的事件,以便您可以彻底验证查询。
答案 2 :(得分:0)
感谢Graeme Tate和GMB,这两种方法都可以正常工作! 我今天学到了一些新东西:)