繁体   English   中英

MySQL日期比较查询

[英]MySQL date comparison query

我的数据库中有此表:

table t

id   |  a   | b  | date_x

1    |  81  | 12 | 2018-03-16
2    |  9   | 54 | 2025-04-21
3    |  81  | 67 | 2018-03-16
4    |  763 | 81 | 2018-03-16
5    |  90  | 22 | 2025-12-08

date_x是DATE类型

我想选择a = 81或b = 81并且date_x在2019-05-28之前的行。

因此,我在MySQL Workbench中执行以下查询:

SELECT * FROM t
WHERE a = '81' OR b = '81'
AND date_x > '2019-05-28';

这是我得到的:

1    |  81  | 12 | 2018-03-16
3    |  81  | 67 | 2018-03-16

我希望2018-03-16不晚于2019-05-28。 此外,为什么只返回2行? date_x列中还有另一个具有相同日期的日期。

该查询返回相同的内容:

SELECT * FROM t
WHERE a = '81' OR b = '81'
AND date_x > str_to_date('2019-05-28', '%Y-$m-%d');

我已执行以下查询以进行调试:

SELECT * FROM t
WHERE a = '81' OR b = '81'
AND date_x < '2019-05-28';

SELECT * FROM t
WHERE a = '81' OR b = '81'
AND date_x < str_to_date('2019-05-28', '%Y-$m-%d');

然后两者都按预期返回:

1    |  81  | 12 | 2018-03-16
3    |  81  | 67 | 2018-03-16
4    |  763 | 81 | 2018-03-16

我阅读了以下问答,但仍然缺少一些内容:

有什么提示吗? 谢谢

您的查询具有以下形式

SELECT * FROM t WHERE condition_a OR condition_b AND condition_c

AND运算符比OR绑定更牢固,因此最终得到

SELECT * FROM t WHERE condition_a OR (condition_b AND condition_c)

我认为这就是混乱的根源。 与日期无关。

您应该将select括在方括号中。 因此,您将获得WHERE a = '81' OR (b = '81' AND date_x >'2019-05-28')

SELECT * FROM t
WHERE (a = '81' OR b = '81')
AND date_x > '2019-05-28';

重入

SELECT * FROM t
WHERE a = '81' AND date_x > '2019-05-28'
UNION ALL 
SELECT * FROM t
WHERE b = '81' AND date_x > '2019-05-28'

可能更有意义,尤其是在考虑性能时,请考虑此表结构和索引。

CREATE TABLE t (
  `id` INTEGER,
  `a` INTEGER,
  `b` INTEGER,
  `date_x` VARCHAR(10)
  , INDEX(a, date_x)
  , INDEX(b, date_x)
);

SELECT * FROM t
WHERE (a = '81' OR b = '81')
AND date_x > '2019-05-28';

无法使用索引,请参阅演示 ,很有可能最终会扫描整个表/索引文件。

由于MySQL优化程序是基于成本的,因此我还包括了这一点 ,以确保对第一个查询的完全扫描不是简单地由记录数量少到触发的。
但这很明显,第二个查询的计划更加稳定。

我相信如果对该索引进行了索引,Oracle数据库将直接在此优化器中进行OR UNION ALL重读。 由于MySQL由Oracle拥有,我希望他们也将它添加到MySQL中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM