【问题标题】:Couldnt identify equality operator of type json[] when using UNION使用 UNION 时无法识别 json[] 类型的相等运算符
【发布时间】:2017-09-28 20:19:06
【问题描述】:

我正在尝试使用 UNION 规则对单个表执行多个查询

我有两张桌子:

  • 项目(id、名称、固定布尔值)
  • 技能(m2m 到项目)

我希望首先获取一组将 pinned 设置为 true 的行,然后用最新条目填充剩余的行(pinned 设置为 false

SELECT
  project.id AS project_id,
  project.name AS project_name,
  array_agg(json_build_object('skill_id', project_skills.id,'name', project_skills.skill)) AS skills
from project
LEFT OUTER JOIN project_skills on project.name = project_skills.project
WHERE project.pinned = true
GROUP BY project_id,project_name

UNION

SELECT
  project.id AS project_id,
  project.name AS project_name,
  array_agg(json_build_object('skill_id', project_skills.id,'name', project_skills.skill)) AS skills
from project
LEFT OUTER JOIN project_skills on project.name = project_skills.project
WHERE project.id != 1 AND project.pinned = false
GROUP BY project_id,project_name
ORDER BY project.create_date DESC LIMIT 5

执行此查询时,我收到以下错误

ERROR:  could not identify an equality operator for type json[]
LINE 7:   array_agg(json_build_object('skill_id', project_skills.id,...

我不明白这个错误。它是否因为试图比较两个结果中的 json 列而失败?

我使用的是 Postgres 9.4。

【问题讨论】:

    标签: json postgresql union


    【解决方案1】:

    结果我所要做的就是使用UNION ALL - 我想这忽略了尝试在查询中比较json 类型。

    【讨论】:

    • 这应该是对 IMSoP 答案的评论。
    • @ErwinBrandstetter 在我得到这篇文章的答案之前,我实际上已经想出了解决方案。我只是添加了我的答案而不是删除帖子。不过我还是接受了他的回答,因为它比我的更有帮助
    【解决方案2】:

    当您使用UNION 时,DBMS 会删除所有重复的行,为此它需要识别两行是否相等/相同。这反过来意味着查看它正在比较的两行的每一列,并确定它们是否相等。

    您看到的错误消息是您的列之一是使用array_agg(json_build_object(...)) 构建的,它产生json[] 类型的值,这意味着“json 值数组”。因为 Postgres 不知道如何比较两个 JSON 值数组,所以它无法确定您的 UNION 是否产生了重复项。

    如果您实际上并不关心删除重复项,最简单的解决方案是使用 UNION ALL 跳过此步骤。

    正如 cmets 中所指出的,如果您确实想要删除重复项,您可以将值转换为定义了比较运算符的值。最通用的解决方案是转换为文本(例如 some_value::textCAST(some_value as text)),但对于 JSON,您可能特别需要 the jsonb type,它在比较时会忽略格式。

    您可以将json 转换为jsonb,或将json[] 转换为jsonb[],或者在此示例中,您可以直接使用array_agg(jsonb_build_object(...)) 而不是array_agg(json_build_object(...)) 构建jsonb

    【讨论】:

    • @Kunkka: 如果UNION需要,另一种选择是将数组转换为jsonb(或相应地将数组转换为jsonb[]),其中相等运算符被定义为。请参阅:stackoverflow.com/a/24296054/939860stackoverflow.com/a/30520760/939860。 (不过,您会丢失原始格式 - 这通常是无关紧要的。)
    • 有同样的问题,我只是在 group by 和 select 中使用 ::text 将值转换为文本,以方便它抱怨的比较。正在构建视图层次结构,因此在更高级别上,我只是在需要时使用::json[] 转换回 json。使用第 9.6 页。
    • 使用distinct 时遇到同样的问题。不需要,所以我把它拿出来了。
    猜你喜欢
    • 1970-01-01
    • 2014-04-30
    • 1970-01-01
    • 1970-01-01
    • 2013-10-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多