我想查找具有數據和日期列的表中的所有日期範圍。 如果一天中沒有數據,則日期範圍將被拆分。在mysql表中查找日期範圍
例如如果表中有直至2015年3月3日
2015年1月1日之間的數據和有在天2015年5月1日和無數據2015年6月2日
然後我想收到的日期範圍
1-1-2015 until 4-1-2015
6-1-2015 until 5-2-2015
7-2-2015 until 3-3-2015
有沒有辦法用MySQL查詢做到這一點?
我想查找具有數據和日期列的表中的所有日期範圍。 如果一天中沒有數據,則日期範圍將被拆分。在mysql表中查找日期範圍
例如如果表中有直至2015年3月3日
2015年1月1日之間的數據和有在天2015年5月1日和無數據2015年6月2日
然後我想收到的日期範圍
1-1-2015 until 4-1-2015
6-1-2015 until 5-2-2015
7-2-2015 until 3-3-2015
有沒有辦法用MySQL查詢做到這一點?
計劃
- 交叉聯接位數一起以模擬日曆表
- 左加入日曆DataSource和識別時的日期不存在
- 爲了在如上所述使用SQL變量RGN和邊界
- 聚集在rgn和邊界上以獲得每個區域
設置
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 |
+-----+------------+------------+
參考
我們其中一個人誤解了這個要求。我認爲這是你,但是這個問題很糟糕,這對我來說可能很容易。 – Strawberry
可能 - 怎麼樣? – amdixon
讓我們拭目以待。 – Strawberry
根據你的描述,你有一個數據集大致如下......
CREATE TABLE my_table
(data CHAR(2) NULL
,date DATE NOT NULL PRIMARY KEY);
INSERT INTO my_table VALUES
('AB','2015-01-01'),
('AB','2015-01-02'),
('AB','2015-01-03'),
('AB','2015-01-04'),
(NULL,'2015-01-05'),
('AB','2015-01-06'),
('...etc.''
假設是正確的,那麼查詢可以是這個樣子......
SELECT a.date start
, MIN(c.date) end
FROM my_table a
LEFT
JOIN my_table b
ON b.date = a.date - INTERVAL 1 DAY
AND b.data IS NOT NULL
LEFT
JOIN my_table c
ON c.date >= a.date
AND c.data IS NOT NULL
LEFT
JOIN my_table d
ON d.date = c.date + INTERVAL 1 DAY
AND d.data IS NOT NULL
WHERE b.date IS NULL
AND c.date IS NOT NULL
AND d.date IS NULL
AND a.data IS NOT NULL
GROUP
BY a.date;
可以做到這兩種方式(在SQL):使用日曆表(如果你有一個)或使用一個便宜的日曆表模擬器與數字上的硬編碼交叉連接。或者您可以在您的應用程序代碼 – amdixon
中執行此操作,以便不存在直接執行該工作的查詢? – vagelis
不是內置的東西。下面的例子顯示如何模擬一個日曆表來做到這一點 – amdixon