我的数据库中有此表:
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME = 'maTable'
date_x是DATE类型
我想选择a = 81或b = 81并且date_x在2019-05-28之前的行。
所以我在MySQL Workbench中执行以下查询:
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
这就是我得到的:
SELECT * FROM t
WHERE a = '81' OR b = '81'
AND date_x > '2019-05-28';
我希望2018-03-16不晚于2019-05-28。此外,为什么只返回2行? date_x列中还有另一个具有相同日期的
。此查询返回相同的内容:
1 | 81 | 12 | 2018-03-16
3 | 81 | 67 | 2018-03-16
我已经执行了以下查询以进行调试:
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');
我阅读了以下问答,但仍然缺少一些内容:
有任何提示吗?谢谢
答案 0 :(得分:2)
您的查询的格式为
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)
我认为这是混乱的来源。与日期无关。
答案 1 :(得分:2)
您应将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';
答案 2 :(得分:1)
重入
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';
无法使用索引,请参见demo,很可能最终会扫描整个表/索引文件。
由于MySQL优化程序是基于成本的,因此我还加入了this,以确保对第一个查询的完全扫描不是简单地由记录数量少到很少触发的。.
但这很明显,第二个查询的计划更加稳定。
我相信,如果对该数据库进行了索引,则可以直接在该优化器中从OR
到UNION ALL
重新进行Oracle数据库操作。由于MySQL由Oracle拥有,我希望他们也将它添加到MySQL中来。