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

PostgreSQL查询JSON分组报错:无法识别相等运算符求解

解决PostgreSQL分组JSON字段报错并获取车辆最新停靠位置的问题

我来帮你搞定这个问题!你遇到的ERROR: could not identify an equality operator for type JSON,本质是PostgreSQL的原生JSON类型没有默认的相等比较运算符,所以当你把position(JSON类型)放到GROUP BY里时,数据库没法判断两个JSON值是否相等,自然就报错了。而且你的原查询还有个逻辑问题:子查询select * from "Config.Tracking" ORDER BY date DESC LIMIT 1是取整个位置表的最后一条记录,不是对应每个车辆会话的最新位置,这也会导致结果不符合预期。

下面给你两种靠谱的解决方案,优先推荐第一种:

方案一:用窗口函数筛选每个会话的最新位置(最优解)

这种方法完全避开了对JSON字段的分组操作,直接通过窗口函数定位每个sessionId对应的最新位置记录,逻辑更清晰,性能也更优:

SELECT
  v."plateNumber",
  v."vehicleId",
  t.position
FROM "Config.Vehicle" v
INNER JOIN "Config.Session" s 
  ON s."vehicleId" = v."vehicleId"
INNER JOIN (
  -- 给每个会话的位置记录按时间倒序排号,取第一条(最新的)
  SELECT
    "sessionId",
    position,
    ROW_NUMBER() OVER (PARTITION BY "sessionId" ORDER BY date DESC) AS rn
  FROM "Config.Tracking"
) t 
  ON t."sessionId" = s."sessionId" 
  AND t.rn = 1 -- 只保留每个会话的最新位置
WHERE s."sessionEnd" IS NOT NULL;

方案二:转换JSON为可比较的类型(仅作补充)

如果你一定要用GROUP BY的方式,可以把JSON类型转换为JSONB类型(PostgreSQL对JSONB支持相等比较),但注意要先修正子查询的逻辑问题:

SELECT
  v."plateNumber",
  v."vehicleId",
  t.position::jsonb AS position
FROM "Config.Vehicle" v
INNER JOIN "Config.Session" s 
  ON s."vehicleId" = v."vehicleId"
INNER JOIN (
  SELECT
    "sessionId",
    position
  FROM (
    SELECT
      "sessionId",
      position,
      ROW_NUMBER() OVER (PARTITION BY "sessionId" ORDER BY date DESC) AS rn
    FROM "Config.Tracking"
  ) sub
  WHERE rn = 1
) t 
  ON t."sessionId" = s."sessionId"
WHERE s."sessionEnd" IS NOT NULL
GROUP BY 1, 2, t.position::jsonb;

不过说实话,方案二有点画蛇添足,因为窗口函数已经帮我们筛选出了唯一的最新记录,根本不需要再GROUP BY了,所以优先用方案一就好。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 08:42:50