使用 UNION 时无法识别 json[] 类型的相等运算符
Posted
技术标签:
【中文标题】使用 UNION 时无法识别 json[] 类型的相等运算符【英文标题】:Couldnt identify equality operator of type json[] when using UNION 【发布时间】: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。
【问题讨论】:
【参考方案1】:结果我所要做的就是使用UNION ALL
- 我想这忽略了尝试在查询中比较json
类型。
【讨论】:
这应该是对 IMSoP 答案的评论。 @ErwinBrandstetter 在我得到这篇文章的答案之前,我实际上已经想出了解决方案。我只是添加了我的答案而不是删除帖子。不过我还是接受了他的回答,因为它比我的更有帮助【参考方案2】:当您使用UNION
时,DBMS 会删除所有重复的行,为此它需要识别两行是否相等/相同。这反过来意味着查看它正在比较的两行的每一列,并确定它们是否相等。
您看到的错误消息是您的列之一是使用array_agg(json_build_object(...))
构建的,它产生json[]
类型的值,这意味着“json 值数组”。因为 Postgres 不知道如何比较两个 JSON 值数组,所以它无法确定您的 UNION
是否产生了重复项。
如果您实际上并不关心删除重复项,最简单的解决方案是使用 UNION ALL
跳过此步骤。
正如 cmets 中所指出的,如果您确实想要删除重复项,您可以将值转换为定义了比较运算符的值。最通用的解决方案是转换为文本(例如 some_value::text
或 CAST(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[]
),其中相等运算符被定义为。请参阅:***.com/a/24296054/939860 或 ***.com/a/30520760/939860。 (不过,您会丢失原始格式 - 这通常是无关紧要的。)
有同样的问题,我只是在 group by 和 select 中使用 ::text
将值转换为文本,以方便它抱怨的比较。正在构建视图层次结构,因此在更高级别上,我只是在需要时使用::json[]
转换回 json。使用第 9.6 页。
使用distinct
时遇到同样的问题。不需要,所以我把它拿出来了。以上是关于使用 UNION 时无法识别 json[] 类型的相等运算符的主要内容,如果未能解决你的问题,请参考以下文章
Webstorm 中的 ESLint 无法识别 React 类型