【问题标题】:Join + date condition in SQL querySQL查询中的联接+日期条件
【发布时间】:2015-09-14 14:24:33
【问题描述】:

我在数据库中有两个表:EventsDates,它们之间存在一对多的关系(一个事件可以同时发生很多日期)。

我想查询数据库以获取未来和过去的事件,如下所示:

  • 获取未来事件的查询应返回日期>= CURDATE()的每个事件以及尚未指定日期的事件...
  • 获取过去事件的查询应仅返回至少分配了一个日期的事件,该日期又应早于 CURDATE()...

我正在使用简单的联接查询数据库,获取过去事件的适当结果(限制不返回没有日期的事件)。但是,对未来事件的查询有点棘手,因为还必须返回没有日期的事件。我愿意接受任何建议。

到目前为止我的尝试:

过去的事件(工作正常):

SELECT dates.*, events.*,
FROM events
JOIN dates on (events.eventID = dates.eventID AND dates.date < CURDATE())
GROUP BY events.eventID
ORDER BY events.eventID ASC

未来活动: ???

SELECT dates.*, events.*,
FROM events
LEFT JOIN dates on (events.eventID = dates.eventID AND dates.date >= CURDATE())
GROUP BY events.eventID
ORDER BY events.eventID ASC

(我知道我对 LEFT JOIN 的尝试无效,因为它还返回过去的事件,没有日期信息(每个字段都为空)。

提前致谢。

【问题讨论】:

  • 如果您只需要明确的未来事件,您可以将 dates.date &gt;= CURDATE() 移动为有子句
  • 不,我需要未来 + 非日期事件。
  • 在这种情况下,您需要在连接之后应用过滤器,因此将 and dates.date>= curdate() 移动到 where 子句并添加 or dates.date 为空。 Where (dates.date&gt;=curdate() OR dates.date is null) 我不经常看到这种需求,但尽管如此
  • 像 xQbert 说的那样把你的条件放在 WHERE 子句中。像你做的那样,你只从日期中获取那些带有 dates.date >=CURDATE() 的记录,不包括那些带有 dates.date = NULL 和 dates.date 的记录

标签: mysql sql join left-join


【解决方案1】:

首先,当您布置它们时,您的查询不需要GROUP BY 子句,因为没有进行聚合(没有countmax 等)。

你必须将“加入逻辑”和“条件逻辑”分开,所以我建议:

过去的事件:

SELECT dates.*, events.*
FROM events
JOIN dates on (events.eventID = dates.eventID)
WHERE dates.date < CURDATE()
ORDER BY events.eventID ASC

未来事件:

SELECT dates.*, events.*
FROM events
LEFT JOIN dates on events.eventID = dates.eventID
WHERE dates.date >= CURDATE()) OR dates.date IS NULL
ORDER BY events.eventID ASC

【讨论】:

  • 非常感谢。这正是我所需要的。
【解决方案2】:

如果 events 表中的记录总是在 dates 表中有记录,那么您可以使用

SELECT dates.*, events.*,
FROM events
JOIN dates on (events.eventID = dates.eventID AND NVL(dates.date, CURDATE()) >= CURDATE())
GROUP BY events.eventID
ORDER BY events.eventID ASC

我想我不明白为什么过去的事件也没有日期。

【讨论】:

    【解决方案3】:

    我什至没有看“过去事件”的查询,因为你说没关系。

    对于未来的事件之一,尝试这样的事情:

    SELECT 
        `events` . *, `dates` . *, MAX(`dates`.`date`) as `maxDate`
    FROM
        `events` AS `events`
            LEFT JOIN
        `dates` AS `dates` ON (`events`.`eventID` = `dates`.`eventID`)
    GROUP BY `events`.`eventID`
    HAVING `maxDate` >= CURDATE()
        OR `dates`.`date` IS NULL
    ORDER BY events.eventID ASC;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-08-21
      • 2019-01-14
      • 2013-12-05
      • 2016-07-03
      • 1970-01-01
      相关资源
      最近更新 更多