繁体   English   中英

MySQL:获取具有连续日期的行

[英]MySQL: get rows with consecutive dates

例如:

    id | date
   ---+------------
    1 | 2011-01-01
    2 | 2011-01-02
    3 | 2011-01-15
    4 | 2011-01-20
    5 | 2011-01-10
    6 | 2011-01-30
    7 | 2011-01-03
    8 | 2011-02-09
    9 | 2011-02-10
    10 | 2011-02-11
    11 | 2011-02-12
    12 | 2011-02-15
    13 | 2011-02-19
    14 | 2011-02-21
    15 | 2011-02-22
    16 | 2011-02-23
    17 | 2011-02-24

例如,以下是一些行(日期现在可能总是按顺序排列)。 多个记录具有相同日期的可能情况 我想获取具有连续日期的行。 例如; 对于以上条目,我想要类似:

   id | date
   ---+------------
    1 | 2011-01-01
    2 | 2011-01-02
    7 | 2011-01-03
    8 | 2011-02-09
    9 | 2011-02-10
    10 | 2011-02-11
    11 | 2011-02-12
    14 | 2011-02-21
    15 | 2011-02-22
    16 | 2011-02-23
    17 | 2011-02-24

我尝试了类似的东西:

SELECT a.id, a.date FROM tbl a
LEFT JOIN tbl b on a.user_id = b.user_id AND a.date = b.date + INTERVAL 1 DAY

但这并没有给我适当的结果,而且速度要慢得多。 因此,请以正确的流程并更快地指导我。

注意:它实际上是一个出勤计划,因此多个用户应具有相同日期的记录。 因此,我需要所有用户具有连续日期的所有记录。

首先在日期列上创建一个索引:

create index idx_tbl_date on tbl(date);

然后,我认为以下将满足您的要求:

select t.*
from tbl t
where exists (select 1 from tbl t2 where t2.date = t.date + interval 1 day) or
      exists (select 1 from tbl t2 where t2.date = t.date - interval 1 day);

这两个存在子句确保您获得序列中的第一个和最后一个日期。 使用索引,这应该表现良好。

并不是那么琐碎,因为第一行或最后一行总是很困难。 这里是

 mysql> SET @a:=NULL;
       SELECT  DISTINCT m.id, m.date
       FROM mytable3 m,
           (SELECT IF(date<=DATE_ADD(@a, INTERVAL 1 DAY), @a, NULL) start,
                  @a:=date next  
                  FROM mytable3 ORDER BY date) m2
       WHERE m.date=m2.start 
            OR (m.date=m2.next AND m2.start IS NOT NULL);

查询正常,受影响的0行(0.00秒)

 +----+------------+
 | id | date       |
 +----+------------+
 |  1 | 2011-01-01 |
 |  2 | 2011-01-02 |
 |  7 | 2011-01-03 |
 |  8 | 2011-02-09 |
 |  9 | 2011-02-10 |
 | 10 | 2011-02-11 |
 | 11 | 2011-02-12 |
 | 14 | 2011-02-21 |
 | 15 | 2011-02-22 |
 | 16 | 2011-02-23 |
 | 17 | 2011-02-24 |
 +----+------------+

设置11行(0.08秒)

如果您不想使用变量,也可以使用以下命令:

       SELECT  DISTINCT m.id, m.date
       FROM mytable3 m,
           (SELECT m1.date start, m2.date next FROM mytable3 m1, mytable3 m2
            WHERE m2.date<=DATE_ADD(m1.date, INTERVAL 1 DAY) AND m2.date>m1.date) m2
       WHERE m.date=m2.start 
            OR (m.date=m2.next AND m2.start IS NOT NULL);
SELECT a.id, a.date FROM a
LEFT JOIN b on a.id = b.id AND a.date <= b.date + INTERVAL '1 day'
ORDER BY a.date;

语法INTERVAL 1 DAY是错误的,我想您正在寻找INTERVAL '1 day' 另外,如果我正确地理解了您的问题,而我可能没有,那么您可能希望使用<=而不是=来检查日期是否在1天之内。 希望这可以帮助。

暂无
暂无

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

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