1

上午 9 点我从以前的帖子中获得了有关查询的帮助,但我有一个新问题。请耐心等待我的解释......

设置,2 个表:cal_events其中包含日历的动态事件和在一天内对其进行更新的重复事件。此外,cal_events_recurring它包含重复事件。下面的查询是一个示例,其中包含将由 PHP 传递的虚拟数据。我从 12 月 15 日开始,所以返回当天的所有活动。重要的部分是重复事件仅在没有匹配的动态对应项时才返回。如果cal_events, is_overwrite= 1 及其overwrite_id= (上午 9:00cal_events_recurring事件的唯一 id,则只返回动态表行。这意味着,“嘿,我是每天上午 9:00 发生的事件(示例),但是看,在 12 月 15 日,9:00 的重复事件已根据动态表更新了当天的唯一 ID =,overwrite_id所以返回那个。”

select * from(
    select
        ifnull(ce.time, cer.time) as time,
        ifnull(ce.title, cer.title) as title,
        ce.is_overwrite
    from cal_events_recurring cer
    left join cal_events ce on ce.overwrite_id = cer.id
    where cer.is_daily = 1
    or cer.day_index = 6
    or cer.day_num = 15
    union
    select time as time, title, is_overwrite 
    from cal_events where date = '2012-12-15' 
    and is_active = 1 and is_overwrite = 0) as e order by time asc

这一切都很好,数据是正确的,问题是is_active字段。我将再次离开上午 9:00 的示例。我为 16 日上午 9:00 创建了一个动态事件,它将覆盖 16 日的重复事件。现在,如果我稍后决定要恢复到常规重复事件,我将is_active匹配动态事件的字段设置为 0。问题是仍然返回动态事件。如果我添加and ce.is_active = 0事件仍然返回。我将如何编写它,以便如果其动态对应项未激活,它仍会返回重复事件?

如果您需要任何其他信息,请告诉我!

编辑*输出:

time      title 
08:00:00  recurring everyday 8am
09:00:00  dynamic 9am update 

(9am should be the recurring event because the dynamic    is_active = 0)
4

1 回答 1

2

将该条件放入ON子句中:

select * from(
    select
        ifnull(ce.time, cer.time) as time,
        ifnull(ce.title, cer.title) as title,
        ce.is_overwrite
    from cal_events_recurring cer
    left join cal_events ce on ce.overwrite_id = cer.id
        and ce.is_overwrite = 1     -- Added this line
    where cer.is_daily = 1
    or cer.day_index = 6
    or cer.day_num = 15
    union
    select time as time, title, is_overwrite 
    from cal_events where date = '2012-12-15' 
    and is_active = 1 and is_overwrite = 0) as e order by time asc
)

将特殊条件放入连接条件意味着您仍然可以获得左连接,但仅适用于应该连接的行。

如果您将条件放在 where 子句中,您将“破坏”左连接和 的意图,ifnull()原因如下:

联接子句中的条件ON在进行联接时执行,因此您不想联接的行不会被联接,也不会将它们的值放入ifnull()函数中。

一个常见的误解是,连接条件只能是“键相关的”,而实际上它们可以是任何东西。


如果将条件放入 where 子句,它会在连接完成执行- where 子句过滤结果集,所以为时已晚 -ifnull()已经有动态表的数据。

于 2012-12-20T19:44:35.120 回答