当天发生事件的天数列表

时间:2013-08-29 13:45:29

标签: mysql

我有一个事件表,每个事件都有一个开始日期和结束日期。

我需要显示一个天数列表,并显示每天发生的事件。

E.g。假设我有关于运行mon-wed的事件和另一个运行tues-thurs的事件,我正在尝试创建一个像这样的表:

Mon: Event 1
Tue: Event 1, Event 2
Wed: Event 1, Event 2
Thu: Event 2

我能看到的唯一方法是通过运行每天的查询或加载给定日期范围的所有事件,然后在我的代码中复制它们,如果它们持续超过一天。这两种方法看起来都很糟糕,我确信我错过了一些东西。

有更简洁的方法吗?

结构:

id         INT
name       VARCHAR
start_date DATE
end_date   DATE

当前查询(稍微简化,因为此数据库结构令人震惊):

SELECT *
FROM events
WHERE start_date <= $somedate
AND end_date >= $somedate

...其中$ somedate是给定日期。 (是的,我正在我的代码中正确地逃避它!)

4 个答案:

答案 0 :(得分:1)

首先,您必须获得每个事件的start_date和end_date之间的所有日期。 放入温度。表格如下:

|Weekday| Event_name|
|Mo     | Event1    |
|Tu     | Event1    |
|We     | Event1    |
|We     | Event2    |
|Th     | Event2    |
|Fr     | Event2    |

然后在工作日按组分组事件。

此链接将帮助您获取每个活动的开始日期和结束日期之间的日期: Get a list of dates between two dates

答案 1 :(得分:1)

这可能是一种更好的方式,但我会说要创建一个可能日期的表格,然后简单地

select * from events
 inner join possibleDates on possibleDates.Date >= start_date and possibleDates.Date <= end_date

答案 2 :(得分:1)

选择特定日期范围内的事件(我假设某个特定月份)。然后循环那个月的日子,并有另一个内部循环,显示该日期发生的任何事件。

<?php
$events = getEvents(); // some function that returns events from database

echo '<ol class="calendar">';
for ($i = 1; $i <= cal_days_in_month(); $i++) {
    echo '<li>';

    $beginning = mktime(0, 0, 0, date('n'), $i, date('Y'));
    $end = mktime(23, 59, 59, date('n'), $i, date('Y'));
    $events_on_day = array();

    foreach ($events as $event) {
        if ($event->start_date <= $end && $event->end_date >= $beginning) {
            $events_on_day[] = $event;
        }
    }

    if ($events_on_day > 0) {
        echo '<ul>';
        foreach ($events_on_day as $event_on_day) {
            echo '<li>' . $event_on_day->name . '</li>';
        }
        echo '</ul>';
    }
}
echo '</ol>';
?>

答案 3 :(得分:1)

如果你必须,你可以在一个查询中完成它,虽然我建议得到像Jan Zeiseweis也建议的工作日表。使用SQLfiddle:http://www.sqlfiddle.com/#!2/e618d9/1/0

SELECT wk.day, GROUP_CONCAT(e.name, '') events
FROM (
  SELECT 'Monday' day, 0 dayIndex
    UNION
  SELECT 'Tuesday' day, 1 dayIndex
    UNION
  SELECT 'Wednesday' day, 2 dayIndex
    UNION
  SELECT 'Thursday' day, 3 dayIndex
    UNION
  SELECT 'Friday' day, 4 dayIndex
    UNION
  SELECT 'Saturday' day, 5 dayIndex
    UNION
  SELECT 'Sunday' day, 6 dayIndex
) wk
LEFT JOIN Events e
   ON WEEKDAY(e.start) <= wk.dayIndex
  AND WEEKDAY(e.end) >= wk.dayIndex
GROUP BY wk.day ORDER BY wk.dayIndex