MySQL BETWEEN AND包含边界值

发布时间 2023-07-18 14:57:44作者: 相由心生,命由己造
select count(1) from table_a where my_date between '20230715' and '20230717';

上面的SQL我们发现只统计了20230715、20230716的数据,没有17日的数据。难道BETWEEN AND不包含边界吗?

MySQL中BETWEEN AND包含边界值吗?答案是肯定的,是包含边界的。那为什么有此疑问呢?

MySQL使用BETWEEN AND关键字进行范围查询,等同于>= && <=。适用于字符串类型、数值类型、日期、日期时间类型。
但是我们在编写SQL时传入的要么是字符串,要么是数值,针对字段的实际类型,会对我们查询条件值进行转化,转化的结果的多样性,就导致我们对于是否包含边界值的误解。出现此误解的主要是DATETIME类型。

再看上面的问题,我们发现my_date字段的类型是DATETIME,实际查询时MySQL将 string('20230715') 转化为了datetime('2023-07-15 00:00:00'),将 string('20230717') 转化成了datetime('2023-07-17 00:00:00'),再带回到SQL中

select count(1) from table_a where my_date between '2023-07-15 00:00:00' and '2023-07-17 00:00:00';

这样和查询结果匹配了。

出现这样的问题,是因为字段命名不规范,同时开发人员没有确认字段的具体类型,根据字段中文名或者英文名,先入为主,误将datetime类型作为date类型来查询,才编写了上面的SQL。实际datetime类型按照日期来过滤数据的写法有很多种,比如如下两种方法

  • 编写完整的时间串作为条件值
-- 要不要考虑时间精度,请根据实际情况编写
select count(1) from table_a where my_date between '2023-07-15 00:00:00' and '2023-07-17 23:59:59.999999';
  • 将字段值转换为date
select count(1) from table_a where date(my_date) between '2023-07-15' and '2023-07-17';
select count(1) from table_a where str_to_date(my_date, '%Y-%m-%d') between '2023-07-15' and '2023-07-17';