You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PostgreSQL考勤表时间范围去重查询报错:运算符不存在boolean = timestamp

解决PostgreSQL查询报错:operator does not exist: boolean = timestamp without time zone

你的SQL语句报错核心是WHERE子句的语法逻辑混乱,具体看这部分:

a.checktime <= '2017-12-05 08:00:00' IN (SELECT checktime FROM checkinout where checktime >='2017-12-05 03:00:00' AND checktime <='2017-12-05 23:00:00')

这里a.checktime <= '2017-12-05 08:00:00'会返回布尔值(true/false),而IN子句返回的是时间戳集合,PostgreSQL没办法把布尔值和时间戳做比较,自然就触发了类型不匹配的错误。

再结合你的需求:要查询2017-11-11 03:00:00到2017-11-11 08:00:00范围内的打卡数据,且这个小范围属于更大的2017-11-11 03:00:00至2017-11-11 23:00:00区间(其实小范围本身就包含在大区间里,除非你想额外限定用户在大区间内有打卡记录),再加上你用DISTINCT ON (a.userid)想要每个用户只返回一条记录的需求,我给你整理了两种修正方案:

方案1:直接查询小时间范围内的用户唯一打卡记录

如果你的需求就是获取每个用户在2017-12-05 03:00:00到2017-12-05 08:00:00内的一条打卡记录(默认按打卡时间排序取第一条,你可以根据需要调整排序规则):

SELECT DISTINCT ON (a.userid) 
    a.userid, 
    b.name, 
    a.checktime 
FROM checkinout a 
LEFT JOIN userinfo b ON a.userid = b.userid 
WHERE a.checktime >= '2017-12-05 03:00:00' 
  AND a.checktime <= '2017-12-05 08:00:00'
ORDER BY a.userid, a.checktime; -- 排序规则决定取用户的哪条记录,比如最早或最晚打卡

方案2:确保用户在大区间内有打卡,再取小范围记录

如果你想先筛选出在2017-12-05 03:00:00至2017-12-05 23:00:00内有打卡的用户,再取他们在小范围内的记录,可以用EXISTS子句实现:

SELECT DISTINCT ON (a.userid) 
    a.userid, 
    b.name, 
    a.checktime 
FROM checkinout a 
LEFT JOIN userinfo b ON a.userid = b.userid 
WHERE a.checktime >= '2017-12-05 03:00:00' 
  AND a.checktime <= '2017-12-05 08:00:00'
  AND EXISTS (
      SELECT 1 FROM checkinout c 
      WHERE c.userid = a.userid 
        AND c.checktime >= '2017-12-05 03:00:00' 
        AND c.checktime <= '2017-12-05 23:00:00'
  )
ORDER BY a.userid, a.checktime;

小提醒:

  • DISTINCT ON (column)是PostgreSQL特有的语法,必须配合ORDER BY子句使用,否则返回的分组第一条记录是随机的,结果不可控。
  • 你的原SQL里写的日期是2017-12-05,但需求描述里是2017-11-11,记得统一成你实际需要的日期哦。

内容的提问来源于stack exchange,提问作者Alvian Cahyadi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 06:22:16