千家信息网

PostgreSQL DBA(109) - pgAdmin(Don't do this:Don't use BETWEEN)

发表于:2026-11-01 作者:千家信息网编辑
千家信息网最后更新 2026年11月01日,no zuo no die系列,来自于pg的wiki。这一节的内容是:不要使用between。理由是:BETWEEN uses a closed-interval comparison: the va
千家信息网最后更新 2026年11月01日PostgreSQL DBA(109) - pgAdmin(Don't do this:Don't use BETWEEN)

no zuo no die系列,来自于pg的wiki。
这一节的内容是:不要使用between。
理由是:

BETWEEN uses a closed-interval comparison: the values of both ends of the specified range are included in the result.
This is a particular problem with queries of the form
SELECT FROM blah WHERE timestampcol BETWEEN '2018-06-01' AND '2018-06-08';
This will include results where the timestamp is exactly 2018-06-08 00:00:00.000000, but not timestamps later in that same day. So the query might seem to work, but as soon as you get an entry exactly on midnight, you'll end up double-counting it.
Instead, do:
SELECT FROM blah WHERE timestampcol >= '2018-06-01' AND timestampcol < '2018-06-08'

原因是between是闭合区间,在处理日期时会丢失精度,比如日期'2018-06-08'会认为是'2018-06-08 00:00:00.000000'而不是'2018-06-08 23:59:59.999999',下面举例说明。

创建数据表并插入数据

[local]:5432 pg12@testdb=# drop table if exists t_between;DROP TABLETime: 4.715 ms[local]:5432 pg12@testdb=# create table t_between(id int,tz timestamptz);CREATE TABLETime: 4.788 ms[local]:5432 pg12@testdb=# [local]:5432 pg12@testdb=# insert into t_between values(1,CURRENT_TIMESTAMP);INSERT 0 1Time: 3.620 ms[local]:5432 pg12@testdb=# insert into t_between values(2,now());INSERT 0 1Time: 2.319 ms[local]:5432 pg12@testdb=# insert into t_between values(3,date_trunc('second',CURRENT_TIMESTAMP));INSERT 0 1Time: 2.542 ms[local]:5432 pg12@testdb=# insert into t_between values(4,date_trunc('day',CURRENT_TIMESTAMP));INSERT 0 1Time: 2.766 ms[local]:5432 pg12@testdb=# select * from t_between order by id; id |              tz               ----+-------------------------------  1 | 2019-10-17 11:47:07.876236+08  2 | 2019-10-17 11:47:07.881309+08  3 | 2019-10-17 11:47:07+08  4 | 2019-10-17 00:00:00+08(4 rows)Time: 1.760 ms

查询数据

[local]:5432 pg12@testdb=# select * from t_between where tz between'2019-10-16' and '2019-10-17'; id |           tz           ----+------------------------  4 | 2019-10-17 00:00:00+08(1 row)Time: 1.691 ms[local]:5432 pg12@testdb=# select * from t_between where tz >= '2019-10-16'  and tz < '2019-10-17'; id | tz ----+----(0 rows)Time: 1.186 ms[local]:5432 pg12@testdb=#

用between会把值为2019-10-17 00:00:00+08的数据输出,因此建议使用普通的比较符(>、<、=等)。

参考资料
Don't Do This

数据 日期 普通 内容 区间 原因 参考资料 建议 数据表 理由 精度 资料 参考 处理 查询 输出 闭合 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 中智农互联网科技 湖北九亚互联网络科技有限公司 中关村互联网 科技集团 华中科技大学互联网 互联网科技小额贷款 互联网科技公司有哪些 老年人脱离互联网科技的作文 深圳国际航运科技和互联网 温州喔噻互联网科技有限公司 科技与互联网哪个更好 移动互联网年度科技创新 国大互联网教育科技有限公司工作 西安小鹰速贷互联网科技有限公司 佛山市拉法互联网科技有限公司 智帮互联网科技公司最近动向 产业互联网科技服务公司 济南小医互联网科技有限公司招聘 江苏互联网智能科技产品出厂价 互联网界的黑科技 小牛互联网科技有限公司地址 上海挚品互联网科技有限公司 广东猪兼强互联网科技有限公司 科技伦理 互联网公司 新华互联网科技2019 福建科技产业互联网发展 从那以后互联网科技有限公司 云鲸互联网络科技有限公司 保山互联网科技靠谱吗 伍佰万互联网科技是干嘛的 颐高云石互联网科技
0