mysql - 在 mysql 表中查找日期范围

标签 mysql date

<分区>

我想在包含数据和日期列的表中查找所有日期范围。 如果一天中没有数据,日期范围将被拆分。

例如,如果一个表有 1-1-2015 到 3-3-2015 之间的数据

5-1-2015 和 6-2-2015 没有数据

那么我想接收日期范围

1-1-2015 until 4-1-2015

6-1-2015 until 5-2-2015

7-2-2015 until 3-3-2015

有没有办法用 mysql 查询来做到这一点?

最佳答案

计划

  • cross join digits together to simulate a calendar table
  • left join calendar to datasource and identify when date not present
  • order over above using sql variables rgn and boundary
  • aggregate over rgn, and boundary to get each region

设置

create table somedates
(
  id integer primary key not null,
  vdate date 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 somedates
( id, vdate )
select @id := @id + 1 as id, date_add('2015-01-01', interval a2.n * 100 + a1.n * 10 + a0.n day) as vdate
from digits_v a2
cross join digits_v a1
cross join digits_v a0
cross join ( select @id := 0 ) params
where date_add('2015-01-01', interval a2.n * 100 + a1.n * 10 + a0.n day) <= date('2015-03-03')
and date_add('2015-01-01', interval a2.n * 100 + a1.n * 10 + a0.n day) not in
(
  '2015-01-05',
  '2015-02-06'
)
;

查询

select rgn, min(boundary) `from`, max(boundary) `to`
from
(
select active.aday, active.present,
@rgn := if(active.present,
           if(@boundary := active.aday, @rgn, @rgn), 
           if(@boundary := null, @rgn + 1, @rgn + 1)) as rgn,
@boundary as boundary
from
(
select date_add('2015-01-01', interval a2.n * 100 + a1.n * 10 + a0.n day) as aday,
case when sd.id is not null then true
     else false
end as present
from digits_v a2
cross join digits_v a1
cross join digits_v a0
left join somedates sd
on sd.vdate = date_add('2015-01-01', interval a2.n * 100 + a1.n * 10 + a0.n day)
where date_add('2015-01-01', interval a2.n * 100 + a1.n * 10 + a0.n day) <= date('2015-03-03')
and date_add('2015-01-01', interval a2.n * 100 + a1.n * 10 + a0.n day) >= date('2015-01-01')
) active
cross join ( select @rgn := 0, @boundary := date('2015-01-01') ) params
order by active.aday
) boundaries
group by rgn
having `from` is not null
;

输出

+-----+------------+------------+
| rgn |    from    |     to     |
+-----+------------+------------+
|   0 | 2015-01-01 | 2015-01-04 |
|   1 | 2015-01-06 | 2015-02-05 |
|   2 | 2015-02-07 | 2015-03-03 |
+-----+------------+------------+

sqlfiddle


引用

关于mysql - 在 mysql 表中查找日期范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33498195/

相关文章:

JavaScript Date.prototype.toISOString() 丢失偏移量

mysql - 对两个表的 SQL 更新查询

php - 必填字段错误检查不起作用

php - 如何按票数对选项进行排序

php - 注意 : Undefined offset: 0, PHP/MySQL

php - mysql - 在所有日期出现的日期之间搜索

查询 bash 脚本中的 Mysql 错误处理

perl - 如何计算Perl中两个日期之间的天数?

android - 将经过的实时时间转换为日期

javascript - 如何从 Javascript 日期中获取年份的最后 2 位数字