Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Well, not so elegant, but working solution using <code>GROUP_CONCAT</code> aggregate function and variables within <code>SELECT</code> to groups similar consecutive days.</p> <p>Your schema and example data set:</p> <pre><code>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) ; </code></pre> <p>The query:</p> <pre><code>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 &lt;=&gt; day_schedule AND days.date &lt;=&gt; 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 ; </code></pre> <p>And the result:</p> <pre><code>| 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 | </code></pre> <p>All that you need to do in PHP is to store last <code>BEG_DATE</code> and <code>END_DATE</code> values to compare them with current ones to decide when to output range header.</p>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload