用SQL计算时间

时间:2014-03-17 06:11:54

标签: mysql sql

在MySQL日历中,项目使用start + duration放置。两个整数,但是:
Start如下所示:YYYYMMDDhhmm,而持续时间只是几分钟。

在插入新项目之前,我必须确保它不会与现有项目重叠 困难部分:是否有任何现有项目的开始+持续时间>我的新项目开始了 在SQL中:计算(YYYYMMDDhhmm + minutes)并返回有效的YYYYMMDDhhmm
这有助start+duration从不导致YYYYMMDD-part更改:)

感谢大家 - 我的(PHP)实现:

$exists = runSQL("SELECT id FROM cal ".
    "WHERE  STR_TO_DATE(start,'%Y%m%d%H%i') + INTERVAL duration MINUTE ".
    "       > ".
    "       STR_TO_DATE( ? ,'%Y%m%d%H%i') ".
    "  AND  STR_TO_DATE(start,'%Y%m%d%H%i') ".
    "       < ".
    "       STR_TO_DATE( ? ,'%Y%m%d%H%i') + INTERVAL ? MINUTE"
    ,array("iii", $start, $start, $minutes ));
if (count($exists) > 0) bitch("Too late - Update your view");

完美地工作但是4次调用STR_TO_DATE() ..

感谢Spencer7593:更快(更短)的版本:

$exists = runSQL("SELECT id FROM cal ".
    "WHERE  start*100 + INTERVAL duration MINUTE > ?*100 + INTERVAL 0 MINUTE ".
    "  AND  start*100 + INTERVAL 0 MINUTE        < ?*100 + INTERVAL ? MINUTE"
    ,array("iii", $start, $start, $minutes ));
if (count($exists) > 0) bitch("Too late, slot taken - Update your view");

3 个答案:

答案 0 :(得分:1)

  

如何(YYYYMMDDhhmm +分钟)并返回有效的YYYYMMDDhhmm(在SQL中)?

一种方法

SELECT t.*, 
       1 * DATE_FORMAT(STR_TO_DATE(start, '%Y%m%d%H%i') + 
                       INTERVAL duration MINUTE, '%Y%m%d%H%i') end
  FROM table_name t

或没有字符串操作

SELECT t.*,
       FLOOR(start / 10000) * 10000 + 
         FLOOR(start MOD 10000 / 100) * 100 + 
           FLOOR((start MOD 100 + duration) / 60) * 100 + 
             (start MOD 100 + duration) MOD 60 end
  FROM calendar t

两种情况的样本输出:

| ID |        START | DURATION |          END |
|----|--------------|----------|--------------|
|  1 | 201403151200 |       60 | 201403151300 |
|  1 | 201403161545 |       35 | 201403161620 |

这是 SQLFiddle 演示

答案 1 :(得分:1)

从整数“开始”表示YYYYMMDDHHMM转换为DATETIME并以分钟为单位添加整数“持续时间”的一种方法是通过乘以100来添加秒部分(从12位数更改为14位数),并且然后添加一个间隔,MySQL将隐式转换整数值为DATETIME。例如:

 t.start*100 + INTERVAL t.duration MINUTE

要仅转换“开始”而不添加“持续时间”,请按照完全相同的方式执行,除非指定文字0代替t.duration。例如:

 t.start*100 + INTERVAL 0 MINUTE

<强>后续

问:这是否隐式转换为字符串并调用STR_TO_DATE,需要“更多计算”而不是使用STR_TO_DATE?

A:我不相信。没有STR_TO_DATE函数,性能测试结果显示更快;这可能意味着它实际上是一个更短的代码路径。

查询1:将整数隐式转换为DATETIME

SELECT /*!40001 SQL_NO_CACHE */ t.start
  FROM demo0317 t
 WHERE ( t.start*100 + INTERVAL t.duration MINUTE ) 
     = STR_TO_DATE('2014-03-17 09:39','%Y-%m-%d %h:%i')

查询2:使用STR_TO_DATE将整数转换为DATETIME

SELECT /*!40001 SQL_NO_CACHE */ t.start
  FROM demo0317 t
 WHERE ( STR_TO_DATE(t.start,'%Y%m%d%h%i') + INTERVAL t.duration MINUTE ) 
     = STR_TO_DATE('2014-03-17 09:39','%Y-%m-%d %h:%i')

查询已用时间:

run  Query 1    Query 2
---  ---------  ----------
 2:  8.129 sec  15.520 sec
 3:  8.124 sec  15.625 sec
 4:  8.125 sec  15.622 sec
 5:  8.123 sec  15.626 sec
---  ---------  ----------
avg  8.125 sec  15.598 sec

答案 2 :(得分:0)

您可以对字符串格式化的日期时间值使用STR_TO_DATE函数。

示例

mysql> select @ts:=str_to_date( '201403161155','%Y%m%d%h%i' ) ts,
    -> @ts + interval 5 minute 'add 5 min';
+---------------------+---------------------+
| ts                  | add 5 min           |
+---------------------+---------------------+
| 2014-03-16 11:55:00 | 2014-03-16 12:00:00 |
+---------------------+---------------------+

在返回的日期时间使用DATE_FORMAT函数,您可以重新应用'%Y%m%d%h%i'以匹配您的数据格式。

mysql> select @ts:=str_to_date( '201403161155','%Y%m%d%h%i' ) ts,
    -> @nts:=(@ts + interval 5 minute) 'add 5 min',
    -> date_format( @nts, '%Y%m%d%h%i' ) nts;
+---------------------+---------------------+--------------+
| ts                  | add 5 min           | nts          |
+---------------------+---------------------+--------------+
| 2014-03-16 11:55:00 | 2014-03-16 12:00:00 | 201403161200 |
+---------------------+---------------------+--------------+