MySQL按时间范围划分

时间:2015-01-23 05:06:31

标签: mysql sql

我的视图有两列,如下所示:

id    hour_from    hour_to
1     12:00        20:00
2     09:00        13:00
3     07:30        19:00
....................

我正在尝试使用单个查询来实现以下目标:

id    hour
1     12:00        
1     12:30        
1     13:00        
1     13:30       
............
1     19:30        
2     09:00        
2     09:30      
2     10:00       
2     10:30   
............
2     12:30   
............

换句话说,我想根据hour_from和hour_to字段将每一行拆分成多行。想知道这是否可行,或者我是否必须编写存储过程来执行此操作。

1 个答案:

答案 0 :(得分:1)

您需要一个包含您想要返回的所有时间的行源。然后,您可以使用JOIN操作来选择要返回的行。

如果您有这样的表:

CREATE TABLE cal (tm TIME NOT NULL PRIMARY KEY) ENGINE=InnoDB ;
INSERT INTO cal (tm)  VALUES ('00:00:00'),('00:30:00');
INSERT INTO cal (tm) SELECT ADDTIME(tm,'01:00:00') FROM cal;
INSERT INTO cal (tm) SELECT ADDTIME(tm,'02:00:00') FROM cal;
INSERT INTO cal (tm) SELECT ADDTIME(tm,'04:00:00') FROM cal;
... 

然后你可以在查询中使用它:

SELECT v.id
     , c.tm
  FROM myview v
  JOIN cal c
    ON c.tm >= v.hour_from
   AND c.tm <= v.hour_to
 ORDER BY v.id, c.tm

如果您想要特定格式的时间值,可以使用DATE_FORMAT功能:

SELECT v.id
     , DATE_FORMAT(c.tm,'%H:%i') AS hour_

这假定视图返回的值是TIME数据类型。如果不是,你会想要转换它们。 (或者您可以使用规范格式处理字符串的相同结果。)

注意:您没有强制要求有一张桌子;它可以是任何行源,例如内联视图。你只需要足够的行(在你的情况下,假设从00:00到23:30增加半小时,即48行。)

如果您有任何时间范围“越过”午夜边界(例如22:00到02:00),示例查询将不会返回任何行。你需要做出调整。

类似的东西:

 JOIN cal c
   ON ( t.hour_from <= t.hour_to 
      AND c.tm >= v.hour_from
      AND c.tm <= v.hour_to
      )
   OR ( t.hour_from > t.hour_to 
      AND (   c.tm <= v.hour_from
          OR  c.tm >= v.hour_to
          )
      )