我有两个桌子
CREATE TABLE `contract` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`emp_id` int(11) DEFAULT NULL ,
`sign_time` datetime DEFAULT NULL ,
`end_time` datetime DEFAULT NULL ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
CREATE TABLE `employee_detail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL ,
`stage` varchar(100) DEFAULT NULL ,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ;
和一些数据:
INSERT INTO `contract` (`id`, `emp_id`,`sign_time`, `end_time`) VALUES
('25', '83', '2018-11-21 00:00:00', '2018-12-01 15:27:00');
INSERT INTO `contract` (`id`, `emp_id`,`sign_time`, `end_time`) VALUES
('26', '94', '2018-11-21 00:00:00', '2018-12-01 15:23:00');
INSERT INTO `employee_detail` (`id`, `name`, `stage`) VALUES ('83', 'Michael',
'1');
INSERT INTO `employee_detail` (`id`, `name`, `stage`) VALUES ('94', 'John',
'1');
当我使用SQL查询数据库时:
SELECT
c.*
FROM
contract c
JOIN employee_detail e ON c.emp_id = e.id
WHERE
e.stage != - 1
AND (
TIMESTAMPDIFF(
MINUTE,
'2018-11-30 09:18:23',
c.end_time
)
) > 0
AND TIMESTAMPDIFF(
MONTH,
'2018-11-30 09:18:23',
c.end_time
) = 0
我有0条记录。 但是,如果我使用SQL查询:
SELECT
c.*
FROM
contract c
JOIN employee_detail e ON c.emp_id = e.id
WHERE
e.stage != - 1
AND (
TIMESTAMPDIFF(
MINUTE,
'2018-11-30 09:18:23',
c.end_time
)
) > '0'
AND TIMESTAMPDIFF(
MONTH,
'2018-11-30 09:18:23',
c.end_time
) = '0'
将整数0转换为字符串'0',我得到了两个正确的记录。 我从https://dev.mysql.com/doc/refman/5.6/en/date-and-time-functions.html#function_timestampdiff进行搜索,发现:
返回datetime_expr2-datetime_expr1,其中datetime_expr1和datetime_expr2是日期或日期时间表达式。一个表达式可以是日期,另一个可以是日期时间。在必要时,将日期值视为具有时间部分“ 00:00:00”的日期时间。结果的单位(整数)由unit参数指定。单位的合法值与TIMESTAMPADD()函数的描述中列出的值相同。
我对Oracle的结果和解释感到困惑。 所以timestampdiff函数返回一个整数值,但是当我在SQL语句中使用它时,我得到了错误的结果,而如果我将其视为字符串值,我得到了正确的答案。谁能解释这个奇怪的现象?非常感谢!
答案 0 :(得分:1)
您不应该检查是否具有这样的指定时间范围的记录,因为MySQL在这种情况下将不使用索引。尝试更改const部分并与列比较。像这样:
在哪里
e.stage != - 1
AND c.end_time < DATE_SUB('2018-11-30 09:18:23', INTERVAL 1 MINUTE)
AND c.end_time > DATE_SUB('2018-11-30 09:18:23', INTERVAL 1 MONTH)
答案 1 :(得分:0)
根据查询中首先使用的谓词,我得到不一致的结果:
nvarchar(50)
id | emp_id | sign_time | end_time | diff_month1 | diff_month | diff_minute1 | diff_minute -: | -----: | :------------------ | :------------------ | ----------: | :--------- | -----------: | :---------- 25 | 83 | 2018-11-21 00:00:00 | 2018-12-01 15:27:00 | 0 | equal | 1808 | greater 26 | 94 | 2018-11-21 00:00:00 | 2018-12-01 15:23:00 | 0 | equal | 1804 | greater
SELECT c.* , TIMESTAMPDIFF(MONTH,'2018-11-30 09:18:23',c.end_time) diff_month1 , case when TIMESTAMPDIFF(MONTH,'2018-11-30 09:18:23',c.end_time) = 0 then 'equal' when TIMESTAMPDIFF(MONTH,'2018-11-30 09:18:23',c.end_time) > 0 then 'greater' end diff_month , TIMESTAMPDIFF(MINUTE,'2018-11-30 09:18:23',c.end_time) diff_minute1 , case when TIMESTAMPDIFF(MINUTE,'2018-11-30 09:18:23',c.end_time) = 0 then 'equal' when TIMESTAMPDIFF(MINUTE,'2018-11-30 09:18:23',c.end_time) > 0 then 'greater' end diff_minute FROM contract c JOIN employee_detail e ON c.emp_id = e.id where TIMESTAMPDIFF(MONTH ,'2018-11-30 09:18:23',c.end_time) = 0 and TIMESTAMPDIFF(MINUTE,'2018-11-30 09:18:23',c.end_time) = 0
id | emp_id | sign_time | end_time | diff_month1 | diff_month | diff_minute1 | diff_minute -: | -----: | :-------- | :------- | ----------: | :--------- | -----------: | :----------
db <>提琴here
此试用版是在MySQL 8.0中进行的,但使用rextester.com在MySQL 5.7.12中却出现了相同的不一致之处