0

我有这个查询:

SELECT 
    e.*, u.name AS event_creator_name 
FROM `edu_events` e 
    LEFT JOIN `edu_users` u 
        ON u.user_id = e.event_creator 
    INNER JOIN `edu_event_participants` 
        ON participant_event = e.event_id && participant_user = 1 
WHERE 
    MONTH(e.event_date_start) = 6 
    AND YEAR(e.event_date_start) = 2013

它工作得很好,但是,如果值:e.event_type 等于 1,我只想执行 INNER JOIN。如果不是,它应该忽略 INNER JOIN。

我已经尝试了一段时间来弄清楚,但解决方案似乎很难实现我的提议(因为它仅适用于选择/特定值)。

我正在考虑类似的事情:

SELECT 
    e.*, u.name AS event_creator_name 
FROM `edu_events` e 
    LEFT JOIN `edu_users` u ON u.user_id = e.event_creator

if(e.event_type == 1) {
    INNER JOIN `edu_event_participants` ON participant_event = e.event_id && participant_user = 1 
}

WHERE MONTH(e.event_date_start) = 6 
AND YEAR(e.event_date_start) = 2013
4

3 回答 3

1

根据@Matthias 的进一步反馈,我编辑了以下内容

-- This will get all events for a given user plus all globals
SELECT 
    e.*, 
    u.name AS event_creator_name 
FROM `edu_users` u 

-- in the events
INNER JOIN `edu_events` e 
    ON (
        -- Get all the ones that the user is participant
        e.event_creator = u.user_id
        -- Or where event_type is 1
        OR 
        e.event_type = 1
    )
    AND e.event_date_start BETWEEN DATE('2013-06-01') AND DATE('2013-07-01')
    
-- Add in event participants even though it doesn't seem to be used?
INNER JOIN `edu_event_participants` AS eep 
    ON eep.participant_event = e.event_id
    AND eep.participant_user = 1
    
-- Add the user ID into the WHERE
WHERE u.user_id = 1;

这可能不会有太多意义,因为感觉好像 edu_event_participants 包含太多信息。 event_creator 应该真正针对事件本身存储,然后 event_participants 只包含事件 ID、用户 ID 和用户类型。

如果您希望让所有用户参与某个事件,最好对该事件进行单独查询以根据 event_id 选择所有用户

关于使用 MONTH() 和 YEAR() 的说明。这将触发表扫描,因为 MySQL 需要将 MONTH() 和 YEAR() 函数应用于所有行以确定哪个匹配 WHERE 语句。如果您改为计算上限和下限(即2013-06-01 00:00:00 <= e.event_date_start < 2013-07-01 00:00:00),那么 MySQL 可以对索引使用更有效的范围扫描(假设存在于 e.event_date_start 上)

于 2013-06-10T23:00:30.250 回答
0

即使右表没有匹配的数据,您所追求的也许是显示左表值?在这种情况下,您可以像这样使用外部联接:

LEFT OUTER JOIN `edu_event_participants` ON participant_event = e.event_id && participant_user = 1 AND e.event_type = 1
于 2013-06-10T22:59:06.460 回答
0

如果我理解正确,您只想要在 edu_event_participants 上有一个具有相同 event_id 和参与者用户 = 1 的条目的结果,但前提是 event_type = 1,但您真的不想从 edu_event_participants 表中获取任何信息。如果是这样的话:

SELECT 
    e.*, u.name AS event_creator_name 
FROM `edu_events` e 
    LEFT JOIN `edu_users` u 
        ON u.user_id = e.event_creator 
WHERE 
    -- as Simon at mso.net suggested
    WHERE e.event_date_start BETWEEN DATE('2013-06-01') AND DATE('2013-07-01')
    -- MONTH(e.event_date_start) = 6 
    -- AND YEAR(e.event_date_start) = 2013
    AND (
        -- either event is public
        e.event_type = 1 or
        -- or the user is in the participants table
        exists
            (select 1 from `edu_event_participants` 
            where participant_event = e.event_id
            AND participant_user = 1)
    )
于 2013-06-10T23:20:38.127 回答