简体   繁体   English

根据剧院日期之间的差距生成结果

[英]Generating results based on gap between dates for a theatre

I am working on an SQL query, where I have 2 tables named Theatre, Movies like this:我正在处理一个 SQL 查询,其中有 2 个名为 Theatre、Movies 的表,如下所示:

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.剧院定期放映相同的电影,直到该特定剧院的放映日期差异超过 2 天。

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.对于剧院,如果放映日期差异超过 2 天,它将更改为电影列表中的下一部电影。

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));

It is a bit complicated;有点复杂; here is an approach using window functions, available in MySQL 8.0.这是一种使用窗口函数的方法,可在 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.据我了解您的问题,您需要将theatre中的行分组,以便稍后分配同一部电影。 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.为此,您可以使用lag()来检索之前的show_date ,并在每次遇到超过 2 天的间隔时进行递增的窗口总和。 Then, you can bring the movie table and assign a movie to each group:然后,您可以带上movie表并为每个组分配一个电影:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM