简体   繁体   English

MySQL - 两个表和两个连接

[英]MySQL - two tables and two joins

I am stuck with one query where I want to do several things: - I have a table with some events, each event has a limited amount of people that can apply to it - In other table I keep record of who applied to which event - On the website, to the user, I want to display only the events that he can apply to (to be more precise, the events he hasn't applied to; once he applies, the event should no longer be visible to the user) AND/OR that number of applied people is less than max_no_people (when an event is full, no need to show it to the user我被一个查询困住了,我想做几件事:-我有一个包含一些事件的表,每个事件都有有限数量的人可以申请它-在另一个表中,我记录了谁申请了哪个事件-在网站上,对用户,我只想显示他可以申请的事件(更准确地说,是他没有申请的事件;一旦他申请,该事件应该不再对用户可见) AND/OR 申请人数少于 max_no_people (当事件已满时,无需向用户显示

I got help from here in another thread, but only for part of the problem.我在另一个线程中从这里获得了帮助,但仅针对部分问题。 Tables look like this:表如下所示:

other_events (eventID, max_no_people, active)
event_applied (eventID, userID)

Here is the query:这是查询:

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)

This query works fine - BUT - for every other user than the currently selected one.此查询工作正常 - 但是 - 对于除当前所选用户之外的所有其他用户。 Let's say you have userID = 42 (which is not in events_applied table paired with eventID = 123):假设您的userID = 42 (不在与 eventID = 123 配对的 events_applied 表中):

other_events其他事件

eventID | max_no_people | active
--------|---------------|-------
   21   |       5       |   1

and in events_applied并在 events_applied

eventID | userID
--------|-------
123     |  10
123     |  11
123     |  12
123     |  13
123     |  14

The Query will return empty row (because event is maxed out and you cannot apply anymore), but if you are userID = 12 (which is in the events_applied table and has eventID pair), the result will look like this:查询将返回空行(因为事件已被最大化,您无法再申请),但如果您是userID = 12 (在 events_applied 表中并具有 eventID 对),结果将如下所示:

no_applied | e.eventID | e.max_no_people | e.active
-----------|-----------|-----------------|---------
 **4**     |     123   |         5       |    1

and hence, the event will be visible and you will be able to apply again and again (I know I have to add some additional controls, but I'll tackle that later).因此,该事件将是可见的,您将能够一次又一次地应用(我知道我必须添加一些额外的控件,但我稍后会解决这个问题)。

So, the problem is that this query somehow discards the row of a current user and doesn't add it into final count.所以,问题是这个查询以某种方式丢弃了当前用户的行并且没有将其添加到最终计数中。

Anybody?有人吗? :) :)

The problem is that in your current query you are only explicitly excluding the entries where the User has applied, and therefore the count is reduced by one.问题是,在您当前的查询中,您只是明确排除了用户应用的条目,因此计数减一。 You instead need to exclude all the events where they applied.相反,您需要排除它们应用的所有事件。

Since you're using a LEFT JOIN you'll need to use a subquery to select all those events and then only join on the events (and not join on the user).由于您使用的是 LEFT JOIN,因此您需要对所有这些事件使用 select 的子查询,然后仅加入事件(而不加入用户)。

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)

The main issue with your query is that you are not correlating the left join ed query on a specific eventID .您的查询的主要问题是您没有left join ed 查询与特定eventID相关联。

Consider the following code:考虑以下代码:

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)

If you run this query in this DB Fiddle with your sample data:如果您使用示例数据在此 DB Fiddle 中运行此查询:

  • with userID = 42 , it returns no record: this is because there is no event available (there is only one event, which is already full)使用userID = 42 ,它不返回任何记录:这是因为没有可用的事件(只有一个事件,已经满了)

  • with userID = 12 , it returns no record: this is because this user already applied to the only available event使用userID = 12时,它不返回任何记录:这是因为该用户已应用于唯一可用的事件

I would suggest creating a more representative dataset, for example by creating another event that is not full, so you can thouroughly validate the query.我建议创建一个更具代表性的数据集,例如通过创建另一个未满的事件,这样您就可以彻底验证查询。

Thank you both Graeme Tate and GMB , both approaches work perfectly: I learned something new today :)谢谢Graeme TateGMB ,这两种方法都非常有效:我今天学到了一些新东西 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM