在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");
答案 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 |
+---------------------+---------------------+--------------+