SQL查询问题:如何筛选2016与2018年的订单数据?
问题与解决方案
错误原因分析
第一个SQL的逻辑错误:
你写的WHERE OrderDate LIKE '2016%' AND '2018%'中,'2018%'属于非空字符串,在SQL里会被判定为TRUE,整个条件等价于OrderDate LIKE '2016%' AND TRUE,因此只会返回2016年的订单。要匹配多个年份,必须用OR连接两个匹配条件。第二个SQL的函数用法错误:
date('2016-%m-%d')是无效的日期函数调用方式,date()需要传入合法的日期字符串,而非带占位符的格式,生成的是无效值,自然匹配不到任何数据。
正确SQL写法
方法1:LIKE + OR(适用于OrderDate为字符串类型的场景)
SELECT OrderID, OrderDate FROM Orders WHERE OrderDate LIKE '2016%' OR OrderDate LIKE '2018%';
方法2:日期范围匹配(适用于OrderDate为日期/时间类型的场景,性能更优,可利用索引)
SELECT OrderID, OrderDate FROM Orders WHERE (OrderDate >= '2016-01-01' AND OrderDate < '2017-01-01') OR (OrderDate >= '2018-01-01' AND OrderDate < '2019-01-01');
用< '2017-01-01'而非<= '2016-12-31',是为了避免漏掉2016年12月31日23:59:59这类带具体时间的订单。
方法3:提取年份(写法简洁,不同数据库函数略有差异)
- MySQL/SQL Server版本:
SELECT OrderID, OrderDate FROM Orders WHERE YEAR(OrderDate) IN (2016, 2018);
- PostgreSQL版本:
SELECT OrderID, OrderDate FROM Orders WHERE EXTRACT(YEAR FROM OrderDate) IN (2016, 2018);
注意:这种写法如果OrderDate字段有索引,可能无法被利用,数据量大时性能不如日期范围写法。
内容的提问来源于stack exchange,提问作者Maikol Rojas
相关产品推荐
相关产品推荐

