我的电影数据库允许用户将数据库输入到会话表中,如下所示:
id | time | movie_id
时间是电影播放的日期时间,movie_id是与电影表相关的键。
现在,我正试图连续几天发现正在播放的电影是相同的。例如,我希望能够显示。
3/6/2013 - 7/6/2013
Iron Man 3 7pm
Second Movie 10pm
ETC...
8/6/2013
Iron Man 3 8pm
9/6/2013 - 11/6/2013
Iron Man 3 7pm
Second Movie 10pm
无论如何使用时间和连续几天进行分组?如果需要,我可以将表格更改为单独的日期和时间值。任何帮助将非常感激。如果这只能在PHP中实现,那么任何有关如何入门的想法也将受到赞赏。
谢谢。如果您有任何问题或者这个问题不够明确,请询问。
答案 0 :(得分:1)
嗯,不是那么优雅,但工作解决方案使用GROUP_CONCAT
聚合函数和SELECT
内的变量来连续几天进行分组。
您的架构和示例数据集:
CREATE TABLE movies (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
title CHAR(64) NOT NULL
);
CREATE TABLE schedule (
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
time TIMESTAMP NOT NULL,
movie_id INT NOT NULL
);
INSERT INTO movies (title) VALUES
('Iron Man 3'),
('Second Movie')
;
INSERT INTO schedule (time, movie_id) VALUES
('2013-06-03 19:00:00', 1),
('2013-06-03 22:00:00', 2),
('2013-06-04 19:00:00', 1),
('2013-06-04 22:00:00', 2),
('2013-06-05 19:00:00', 1),
('2013-06-05 22:00:00', 2),
('2013-06-06 19:00:00', 1),
('2013-06-06 22:00:00', 2),
('2013-06-07 19:00:00', 1),
('2013-06-07 22:00:00', 2),
('2013-06-08 20:00:00', 1),
('2013-06-09 19:00:00', 1),
('2013-06-09 22:00:00', 2),
('2013-06-10 19:00:00', 1),
('2013-06-10 22:00:00', 2),
('2013-06-11 19:00:00', 1),
('2013-06-11 22:00:00', 2),
('2013-06-13 19:00:00', 1),
('2013-06-13 22:00:00', 2)
;
查询:
SELECT
DATE_FORMAT(min_date, '%e/%c/%Y') AS beg_date,
DATE_FORMAT(max_date, '%e/%c/%Y') AS end_date,
title,
LOWER(TIME_FORMAT(time, '%l%p')) AS `movie_time`
FROM
(SELECT
MIN(min_date) AS min_date,
MAX(max_date) AS max_date,
range_schedule
FROM
(SELECT
@min_date :=
IF(@range_schedule <=> day_schedule
AND days.date <=> ADDDATE(@max_date, 1),
@min_date,
days.date
) AS min_date,
@max_date := days.date AS max_date,
@range_schedule := days.day_schedule AS range_schedule
FROM
(
SELECT DATE(time) AS `date`, GROUP_CONCAT(CONCAT(TIME(time), '-', movie_id) ORDER BY time) AS day_schedule
FROM schedule
GROUP BY DATE(time)
ORDER BY DATE(time)
) AS days,
(SELECT
@min_date := '0000-00-00',
@max_date := '0000-00-00',
@range_schedule := NULL
) r
) days_of_ranges
GROUP BY min_date, range_schedule
) ranges
JOIN schedule ON DATE(schedule.time) = ranges.min_date
JOIN movies ON movies.id = movie_id
ORDER BY min_date, time
;
结果:
| BEG_DATE | END_DATE | TITLE | MOVIE_TIME |
-----------------------------------------------------
| 3/6/2013 | 7/6/2013 | Iron Man 3 | 7pm |
| 3/6/2013 | 7/6/2013 | Second Movie | 10pm |
| 8/6/2013 | 8/6/2013 | Iron Man 3 | 8pm |
| 9/6/2013 | 11/6/2013 | Iron Man 3 | 7pm |
| 9/6/2013 | 11/6/2013 | Second Movie | 10pm |
| 13/6/2013 | 13/6/2013 | Iron Man 3 | 7pm |
| 13/6/2013 | 13/6/2013 | Second Movie | 10pm |
您需要在PHP中执行的操作是存储最后BEG_DATE
和END_DATE
值,以便将它们与当前值进行比较,以确定何时输出范围标题。