所以我基本上有一张桌子,每个房间每天有一个条目。我需要找到在该房间,财产和备注上分组的所有连续日的开始和结束日期。
property room date notes
----------------------------------------------
2 101 2013-01-01 abc
2 101 2013-01-02 abc
2 101 2013-01-03 abc
2 101 2013-01-04 abc
2 101 2013-01-05 xyz
2 101 2013-01-06 xyz
2 101 2013-01-15 abc
2 101 2013-01-16 abc
2 101 2013-01-17 abc
2 107 2013-01-02 def
2 107 2013-01-03 def
2 109 2013-01-01 abc
2 109 2013-01-02 abc
3 101 2012-12-31 abc
3 101 2013-01-01 abc
3 101 2013-01-02 abc
我需要能够基于属性和日期查询它。当我按日期搜索时,我应该能够在序列的“开始日期”之后使用日期,并且仍然可以找到正确的开始日期。因此,如果我搜索说WHERE date ='2013-01-02'我应该返回类似的内容:
property room start_date end_date notes
----------------------------------------------------
2 101 2013-01-01 2013-01-04 abc
2 107 2013-01-02 2013-01-03 def
2 109 2013-01-01 2013-01-02 abc
3 101 2012-12-31 2013-01-02 abc
这将与一个相当大的表一起使用并返回数十万个结果,因此效率是主要关注点。我发现并试图将一些例子全部用于问题。如果它在WHERE日期条款之前,大多数都太慢,或者不会返回正确的开始日期等。
非常感谢任何帮助。
谢谢!
答案 0 :(得分:0)
您可以使用group by
:
select property, room, min(date) as start_date, max(date) as end_date, notes
from table t
group by property, room, notes;
使用having
子句获取特定日期的行:
select property, room, min(date) as start_date, max(date) as end_date, notes
from table t
group by property, room, notes
having date( '2013-01-02') between min(date) and max(date);
我不确定是否有更高效的方法,尽管这确实需要对整个表进行聚合。
答案 1 :(得分:0)
分析大型数据集并不是MySQL的强项,所以我怀疑你很难获得出色的性能。这个查询似乎可以解决手头的问题,但不一定是最快的;
SELECT r.property, r.room,
MAX(IF(rr.date<=r.date AND is_start, rr.date, NULL)) start_date,
MIN(IF(rr.date>=r.date AND is_end, rr.date, NULL)) end_date,
r.notes
FROM rooms r
JOIN (SELECT r.*, IF(ry.room IS NULL, 1, 0) is_start,
IF(rt.room IS NULL, 1, 0) is_end
FROM (SELECT *, DATE_SUB(date, INTERVAL 1 DAY) yesterday,
DATE_ADD(date, INTERVAL 1 DAY) tomorrow FROM rooms) r
LEFT JOIN rooms ry
ON r.property=ry.property AND r.room=ry.room AND r.notes=ry.notes
AND r.yesterday=ry.date
LEFT JOIN rooms rt
ON r.property=rt.property AND r.room=rt.room AND r.notes=rt.notes
AND r.tomorrow=rt.date
WHERE ry.room IS NULL OR rt.room IS NULL) rr
ON r.property = rr.property AND r.room = rr.room AND r.notes = rr.notes
WHERE r.date = '2013-01-02'
GROUP BY r.property, r.room, r.notes
An SQLfiddle to test with。请注意小提琴中的索引应该加快速度。