我的视图有两列,如下所示:
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字段将每一行拆分成多行。想知道这是否可行,或者我是否必须编写存储过程来执行此操作。
答案 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
)
)