MySQL为给定状态填充两个日期之间缺少的日期

MySQL为给定状态填充两个日期之间缺少的日期,mysql,date,Mysql,Date,我有一个项目数据集。项目从开始到结束都会更改状态,状态更改的日期记录在一个表中(表名为“事件”-不是我的选择)。将如下所示(简化): 在任何给定的日期范围内(动态确定),我希望能够看到哪些项目处于哪个状态。但是,对数据使用BETWEEN或其他查询将只提取在该期间状态发生更改的项目,而不是仍处于给定状态的项目 我目前在Excel中创建了一个非常笨拙的解决方案,它在状态更改日期之间将行复制到新行中,如下所示: Date Status 2015-06-01 Project

我有一个项目数据集。项目从开始到结束都会更改状态,状态更改的日期记录在一个表中(表名为“事件”-不是我的选择)。将如下所示(简化):

在任何给定的日期范围内(动态确定),我希望能够看到哪些项目处于哪个状态。但是,对数据使用BETWEEN或其他查询将只提取在该期间状态发生更改的项目,而不是仍处于给定状态的项目

我目前在Excel中创建了一个非常笨拙的解决方案,它在状态更改日期之间将行复制到新行中,如下所示:

Date          Status  
2015-06-01    Project start
2015-06-02    Project start (copied)
2015-06-03    Stage 2 
2015-06-04    Stage 2 (copied)
2015-06-05    Stage 2 (copied)
2015-06-06    Stage 2 (copied)
2015-06-07    Stage 3
此解决方案允许我查询项目的状态,例如2015-06-06,并查看它仍处于第2阶段

是否有某种方法可以使用mySql提取相同的数据,但作为查询的输出?我听过一些人建议使用日历表,但我不确定这将如何工作。我也看到有人推荐交叉连接,但同样,我无法从描述中理解它是如何工作的


提前感谢您的帮助

您不需要创建包含所有日期的表。您可以更改表格,为每个状态提供开始和结束日期,并使用BEVERY语句

或者使用现有数据

使用@datequery作为要查找其状态的日期

Select top 1 Status from Events
where Date <= @datequery and Date 
order by Date desc
计划

  • 通过交叉连接日历期间的数字和日期来创建日历表

  • 将您的数据加入带有日期的日历源谢谢amdixon。我回到办公室后会试一试的。同时,我将努力弄清楚它的含义:)我以前从未使用过交叉连接,我想知道它们的用途。交叉连接意味着从左数据集和右数据集获取所有记录的组合。因此,如果将一个有2条记录的数据集与一个有5条记录的数据集交叉连接,那么最终将得到一个有10条记录的数据集。退房在这种情况下,这是一种生成数字sequence@RyanVincent是的,您可以将其用作日历填充的现成数据源(用于序列生成)。效率可能不是一个问题,因为日历负载每年最多只发生一次。只需确保id序列中没有间隙。。
    Select top 1 Status from Events
    where Date <= @datequery and Date 
    order by Date desc
    
    @datequery = 2015-06-06
    
    Status
    Stage 2
    
    drop table if exists calendar_t;
    CREATE TABLE calendar_t (
      id integer primary key auto_increment not null,
      `date` date not null,
      day varchar(9) not null,
      month varchar(13) not null,
      `year` integer not null
    );
    
    drop view if exists digits_v;
    create view digits_v
    as
    select 0 as n
    union all
    select 1
    union all
    select 2
    union all
    select 3
    union all
    select 4
    union all
    select 5
    union all
    select 6
    union all
    select 7
    union all
    select 8
    union all
    select 9
    ;
    
    insert into calendar_t
    ( `date`, day, month, `year` )
    select 
    date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day) as `date`,
    dayname(date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day)) as day,
    monthname(date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day)) as month,
    year(date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day)) as `year`
    from
    digits_v a2
    cross join digits_v a1
    cross join digits_v a0
    order by date_add('2015-01-01', interval 100*a2.n + 10*a1.n + a0.n day)
    ;
    
    drop table if exists example;
    create table example
    (
      `date` date not null,
      status varchar(23) not null
    );
    
    insert into example
    ( `date`, status )
    values
    ( '2015-06-01',  'Start'   ),
    ( '2015-06-03',  'Stage 2' ),
    ( '2015-06-07',  'Stage 3' )
    ;
    
    select cal_date, mdate, ex2.status
    from
    (
    select cal_date, max(ex_date) as mdate
    from
    (
    select cal.`date` as cal_date, ex.`date` as ex_date
    from calendar_t cal
    inner join example ex
    on ex.`date` <= cal.`date`
    ) maxs
    group by cal_date
    ) m2
    inner join example ex2
    on m2.mdate = ex2.`date`
    -- pick a reasonable end date for filtering..
    where cal_date <= date('2015-06-15')
    order by cal_date
    ;
    
    +------------------------+------------------------+---------+
    |        cal_date        |         mdate          | status  |
    +------------------------+------------------------+---------+
    | June, 01 2015 00:00:00 | June, 01 2015 00:00:00 | Start   |
    | June, 02 2015 00:00:00 | June, 01 2015 00:00:00 | Start   |
    | June, 03 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 |
    | June, 04 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 |
    | June, 05 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 |
    | June, 06 2015 00:00:00 | June, 03 2015 00:00:00 | Stage 2 |
    | June, 07 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 08 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 09 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 10 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 11 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 12 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 13 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 14 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    | June, 15 2015 00:00:00 | June, 07 2015 00:00:00 | Stage 3 |
    +------------------------+------------------------+---------+