使用UNION时无法识别json[]类型的相等运算符
我正在尝试使用使用UNION时无法识别json[]类型的相等运算符,json,postgresql,union,Json,Postgresql,Union,我正在尝试使用联合规则对单个表执行多个查询 我有两张桌子: 项目(id、名称、固定布尔值) 技能(m2m到项目) 我希望首先得到一个数组,其中固定的设置为真,并用最新的条目填充剩余的行(固定的设置为假) 执行此查询时,我得到以下错误 我不理解这个错误。它失败是因为它试图比较两个结果中的json列吗 我使用的是Postgres 9.4。结果证明我所要做的就是使用UNION all——我想这忽略了在查询中比较json类型。当你使用UNION时,DBMS会删除任何重复的行,为了做到这一点,它需要确
联合规则对单个表执行多个查询
我有两张桌子:
- 项目(id、名称、固定布尔值)
- 技能(m2m到项目)
我希望首先得到一个数组,其中固定的
设置为真
,并用最新的条目填充剩余的行(固定的
设置为假
)
执行此查询时,我得到以下错误
我不理解这个错误。它失败是因为它试图比较两个结果中的json列吗
我使用的是Postgres 9.4。结果证明我所要做的就是使用UNION all
——我想这忽略了在查询中比较json
类型。当你使用UNION
时,DBMS会删除任何重复的行,为了做到这一点,它需要确定两行是否相等/相同。这又意味着要查看正在比较的两行中的每一列,并确定它们是否相等
您看到的错误消息是,其中一列是使用array\u agg(json\u build\u object(…)
构建的,它生成类型为json[]
的值,意思是“json值数组”。因为Postgres不知道如何比较两个JSON值数组,所以它无法确定您的UNION
是否产生了重复
如果您实际上并不关心删除重复项,最简单的解决方案是使用UNION ALL
,它跳过了这一步
正如在注释中指出的,如果确实要删除重复项,可以将值强制转换为定义了比较运算符的值。最通用的解决方案是强制转换为文本(例如some_value::text
或cast(some_value as text)
),但对于您可能特别想要的JSON,这将在比较时忽略格式设置
您可以将json
转换为jsonb
,或者将json[]
转换为jsonb[]
,或者在本例中,您可以直接使用array\u agg(jsonb\u build\u object(…)
而不是array\u agg(json\u build\u object(…))构建
这应该是对IMSoP答案的评论。@ErwinBrandstetter在我得到这篇文章的答案之前,我已经找到了解决方案。我只是添加了我的答案,而不是删除帖子。尽管如此,我还是接受了他的回答,因为他的回答比我的回答更有帮助mine@Kunkka:如果需要联合
,一种替代方法是将数组强制转换为jsonb
(或相应地将数组强制转换为jsonb[]
),为此定义了相等运算符。见:或。(虽然您丢失了原始格式-这通常是不相关的。)也有同样的问题,我只是使用group by和select中的::text
将值转换为文本,以便于进行它所抱怨的比较。我正在构建视图的层次结构,因此在更高的层次上,我只是在需要时通过::json[]
回溯到json。使用第9.6页时,使用distinct
时出现了相同的问题。我不需要它,所以我就把它拿了出来。
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,...