Generating results based on gap between dates for a theatre

learner :

I am working on an SQL query, where I have 2 tables named Theatre, Movies like this:

Theatre

Theatre with columns theatre id and show date:

id      show_date
------------------
1       2018-05-01
2       2018-05-01
1       2018-05-03
3       2018-05-04
2       2018-05-14
3       2018-05-11
2       2018-05-14

Movie

Movie with columns movie id and movie name:

id  name
----------
1   Avatar
2   Spiderman
3   Avengers

A theatre shows the same movies regularly until the show date difference for that particular theatre is more than 2 days.

For a theatre, if the show date difference is more than 2 days it changes to the next movie in the list of movies table.

All theatres show movies in the same order.

Now I want to write a query for this scenario.

The expected output is: (I added comments for each row as an explanation)

theatre_id  show_date   movie
---------------------------------------------

1           2018-05-01  Avatar  /* 1st theatre, 1st date occurrence so picking 1st movie
2           2018-05-01  Avatar  /* 2nd theatre, 1st date occurrence so picking 1st movie */
1           2018-05-03  Avatar  /* 1st theatre, with 1 day gap (1st may 2018 to 3rd may 2018), so picking 1st movie
3           2018-05-04  Avatar  /* 3rd theatre, 1st date occurrence so picking 1st movie */
2           2018-05-10  Spiderman /* 2nd theatre, with 8 days gap (1st may 2018 to 10th may 2018), so picking 2nd movie */
3           2018-05-11  Spiderman /* 3rd theatre, with 6 days gap (4th may 2018 to 11th may 2018) so picking 2nd movie */
2           2018-05-14  Avengers /* 2nd theatre, with 3 days gap (10th may 2018 to 14th may 2018), so picking 3rd movie */

Scripts:

drop table if exists theatre;

CREATE TABLE theatre ( 
  id INTEGER NOT NULL,
  show_date date NOT NULL
);

drop table if exists movie;

CREATE TABLE movie ( 
  id INTEGER NOT NULL PRIMARY KEY AUTO_INCREMENT,
  name VARCHAR(60) NOT NULL
);


insert into movie values (null, 'Avatar');
insert into movie values (null, 'Spiderman');
insert into movie values (null, 'Avengers');

insert into theatre values( 1, cast('2018-05-01' as date));
insert into theatre values( 2, cast('2018-05-01' as date));
insert into theatre values( 1, cast('2018-05-03' as date));
insert into theatre values( 3, cast('2018-05-04' as date));
insert into theatre values( 2, cast('2018-05-10' as date));
insert into theatre values( 3, cast('2018-05-11' as date));
insert into theatre values( 2, cast('2018-05-14' as date));
GMB :

It is a bit complicated; here is an approach using window functions, available in MySQL 8.0.

As I understand your question, you need to put rows from theatre in groups that will later on be assigned the same movie. For this, you can use lag() to retrieve the previous show_date, and make a window sum that increments everytime a gap of more than 2 days is met. Then, you can bring the movie table and assign a movie to each group:

select t.id, t.show_date, m.name movie
from (
    select 
        t.*, 
        sum(case when show_date <= lag_show_date + interval 2 day then 0 else 1 end) 
            over(partition by id order by show_date) grp
    from (
        select 
            t.*, 
            lag(show_date) over(partition by id order by show_date) lag_show_date
        from theatre t
    ) t
) t
inner join (
    select m.*, row_number() over(order by id) grp from movie m
) m
    on m.grp = t.grp

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=372302&siteId=1