我的数据库中有以下表格之一,其中显示了“显示创建表格”的输出。分享:
CREATE TABLE `clues_rma_efficacy_triggers` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`data` int(11) NOT NULL DEFAULT '0',
`data_type` char(1) NOT NULL,
`parent_key_id` tinyint(3) NOT NULL DEFAULT '0',
`child_key_id` tinyint(3) NOT NULL DEFAULT '0',
`parent_flag` tinyint(3) NOT NULL DEFAULT '0',
`child_flag` tinyint(3) NOT NULL DEFAULT '0',
`datetime` int(11) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `data_child_key` (`data`,`parent_key_id`,`child_key_id`),
KEY `idx_pki_cf_cki` (`parent_key_id`,`child_flag`,`child_key_id`),
KEY `idx_pki_pf` (`parent_key_id`,`parent_flag`),
KEY `idx_cki_cf` (`child_key_id`,`child_flag`)
) ENGINE=InnoDB AUTO_INCREMENT=32436413 DEFAULT CHARSET=latin1
如您所见,datetime列是int字段,其中我存储unix_time值。但是我为SELECT查询之一获得了意外行为。生产步骤如下:
1个样本插入:
INSERT INTO `clues_rma_efficacy_triggers` (`data`,`data_type`,`parent_key_id`,`datetime`) VALUES (1234568197,'R',89,1522933144);
mysql> select * from clues_rma_efficacy_triggers where data = 1234568197;
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+
| id | data | data_type | parent_key_id | child_key_id | parent_flag | child_flag | datetime | deleted_flag |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+
| 34905336 | 1234568197 | R | 89 | 0 | 0 | 0 | 1522933144 | 0 |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+
1 row in set (0.01 sec)
下面的查询不应该获取结果,但是它正在获取结果(它忽略了完整的datetime子句并且正在处理parent_key_id和parent_flag)
SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE datetime BETWEEN (NOW( ) - ( 86400 *30 )) AND NOW( ) AND parent_key_id =89 AND parent_flag =0 LIMIT 200;
mysql> SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE datetime BETWEEN (NOW( ) - ( 86400 *30 )) AND NOW( ) AND parent_key_id =89 AND parent_flag =0 LIMIT 200 ;
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+---------------------------+
| id | data | data_type | parent_key_id | child_key_id | parent_flag | child_flag | datetime | deleted_flag | from_unixtime( datetime ) |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+---------------------------+
| 34905336 | 1234568197 | R | 89 | 0 | 0 | 0 | 1522933144 | 0 | 2018-04-05 18:29:04 |
+----------+------------+-----------+---------------+--------------+-------------+------------+------------+--------------+---------------------------+
1 row in set, 2 warnings (0.01 sec)
收到警告:
mysql> SHOW WARNINGS;
+---------+------+-----------------------------------------------------------------------+
| Level | Code | Message |
+---------+------+-----------------------------------------------------------------------+
| Warning | 1292 | Incorrect datetime value: '1522933144' for column 'datetime' at row 1 |
| Warning | 1292 | Incorrect datetime value: '20180407571651' |
+---------+------+-----------------------------------------------------------------------+
2 rows in set (0.01 sec)
当我转换部分之间的第一个子句时,这是输出:
mysql> SELECT (NOW( ) - ( 86400 *30 ));
+--------------------------+
| (NOW( ) - ( 86400 *30 )) |
+--------------------------+
| 20180407571651 |
+--------------------------+
1 row in set (0.00 sec)
Between的第二个条款当然是当前日期。 所以解析后的查询应该成为:
SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE DATETIME BETWEEN 20180407571651 AND '2018-04-10 16:07:00' AND parent_key_id =89 AND parent_flag =0 LIMIT 200;
当然不是取结果。
mysql> SELECT * , from_unixtime( datetime ) FROM clues_rma_efficacy_triggers WHERE DATETIME BETWEEN 20180407571651 AND '2018-04-10 16:07:00' AND parent_key_id =89 AND parent_flag =0 LIMIT 200;
Empty set, 1 warning (0.00 sec)
收到警告:
mysql> SHOW WARNINGS; +---------+------+---------------------------------------------------------+
| Level | Code | Message |
+---------+------+---------------------------------------------------------+
| Warning | 1292 | Truncated incorrect DOUBLE value: '2018-04-10 16:07:00' |
+---------+------+---------------------------------------------------------+
1 row in set (0.01 sec)
我很困惑第一个查询是如何工作的。 Where
子句仅包含AND
条件。它应该立即失败,因为在解析的查询中datetime子句不正确。 Verison输出:
mysql> SELECT VERSION();
+-----------------+
| VERSION() |
+-----------------+
| 10.1.12-MariaDB |
+-----------------+
1 row in set (0.00 sec)