Php 按日期分组观看电影
“我的电影数据库”允许用户将数据库输入会话表,如下所示:Php 按日期分组观看电影,php,mysql,database,movies,Php,Mysql,Database,Movies,“我的电影数据库”允许用户将数据库输入会话表,如下所示: id | time | movie_id 其中time是播放电影的日期时间,movie_id是与movies表相关的键 现在,我试图找到连续几天播放的电影都是一样的。例如,我希望能够显示 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 7p
id | time | movie_id
其中time是播放电影的日期时间,movie_id是与movies表相关的键
现在,我试图找到连续几天播放的电影都是一样的。例如,我希望能够显示
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中实现,那么任何关于如何开始的想法都将不胜感激
多谢各位。如果您有任何问题或这个问题不够清楚,请提问。好吧,不太优雅,但可以使用
GROUP\u CONCAT
聚合内的函数和变量,选择将类似的连续天数分组
您的架构和示例数据集:
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
;
在PHP中需要做的就是存储lastBEG_DATE
和END_DATE
值,将它们与当前值进行比较,以决定何时输出范围标头。是的,在PHP中可能比在SQL中更容易。只需按时间、电影id
订购电影,选择所有,直到第二天,然后将结果与昨天的结果进行比较。如果相同,则忽略;如果不相同,则将昨天设置为新范围的结束日期,将今天设置为开始日期。如果这有道理的话:)@JoachimIsaksson我在想这个。但这意味着PHP可能有大量的数据集需要排序。您对获取页面所需的数据没有任何其他限制,比如开始日期/结束日期吗?也许,GROUP_CONCAT
aggregate函数可以帮助您创建日期表示,然后通过这些表示来累积天数。正如@Olexa所说,GROUP_CONCAT可以帮助每天获取一行,在PHP中解析可能更简单;这似乎工作得很好,只是它没有意识到天亮。例如,如果我在数据库中的唯一内容是3部《钢铁侠》电影,它们都是在3号、12号和20号早上7点拍摄的,那么我的开始日期将是3号,结束日期将是20号。而不是返回3个选项。
| 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 |