【问题标题】:Mysql left join, overwrite row only if field is_active = 1Mysql左连接,仅当字段is_active = 1时才覆盖行
【发布时间】:2012-12-20 18:42:49
【问题描述】:

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

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

【问题讨论】:

  • 您的预期输出如何?
  • 我添加了一些输出,您可以看到动态事件仍然被拉动,即使它的 is_active 字段 = 0。它应该拉动重复事件。
  • 试试inner join 和(可能)union distinct
  • 问题是我仍然必须返回所有未被覆盖的重复事件。如果我做了内部连接,它不会返回那些,对吗?
  • 是的,我在想第一次加入是另一个方向。您需要另一个工会来进行内部联接...

标签: mysql join union


【解决方案1】:

将该条件放入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 子句 filter 结果集,所以为时已晚 - ifnull() 已经有动态表的数据。

【讨论】:

  • @Naterade np - 我已经编辑了答案以提供一些解释。 (顺便说一句,我关注了您对上一个问题中另一个问题的评论)。
  • 不需要日期检查来防止其他一天的一次性事件覆盖指定的重复事件吗?是否不需要进行 is_active 检查来防止不活跃的日常事件覆盖活跃的重复事件?
猜你喜欢
  • 2015-05-03
  • 2012-01-05
  • 2011-07-10
  • 2021-12-07
  • 2012-12-20
  • 1970-01-01
  • 2017-10-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多