mysql 5.6 timestampdiff返回结果问题

iqih9akk  于 2021-06-18  发布在  Mysql
关注(0)|答案(2)|浏览(396)

我有两张table

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,我发现:
返回日期时间表达式2− datetime_expr1,其中datetime_expr1和datetime_expr2是日期或日期时间表达式。一个表达式可以是日期,另一个表达式可以是日期时间;如果需要,日期值将被视为时间部分为“00:00:00”的日期时间。结果的单位(整数)由unit参数给出。unit的合法值与timestampadd()函数描述中列出的值相同。
我对预言的结果和解释感到困惑。所以timestampdiff函数返回一个整数值,但是当我在sql语句中使用它时,我得到了一个不正确的结果,而如果我将它作为字符串值处理,我得到了正确的答案。有人能解释这个奇怪的现象吗?谢谢!

ttygqcqt

ttygqcqt1#

您不应该检查像这样具有指定时间范围的记录,因为mysql在这种情况下不会使用索引。尝试更改const部分并与column进行比较。像这样:
哪里

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)
djp7away

djp7away2#

根据查询中首先使用哪个 predicate ,我会得到不一致的结果:

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
-: | -----: | :------------------ | :------------------ | ----------: | :--------- | -----------: | :----------
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(MINUTE,'2018-11-30 09:18:23',c.end_time) = 0
  and TIMESTAMPDIFF(MONTH ,'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<>在这里摆弄
这个试用版是在MySQL8.0中进行的,但是我在使用rextester.com的MySQL5.7.12中得到了相同的不一致性

相关问题