没有实现匿名复合类型的输入 - Postgres

时间:2018-06-13 11:12:21

标签: sql postgresql

我有一个包含XML列的表。 XML可以包含可选的链接元素。

<Link ReasonCode="MultiLabel">
  <UUID>1d177dee-1da4-4451-b175-396666afc370</UUID>
</Link>

我想从表中获取没有link元素的所有记录。从那些具有link元素的记录中,我只想获取DISTINCT记录。如果两个记录具有相同的链接元素,则跳过第二个匹配项。我试过的查询,

SELECT DISTINCT cast((xpath('/Data/Link', xmldata)) AS TEXT) 
FROM tblData AS link 
WHERE link != '{}'
  

错误:未实现匿名复合类型的输入

  1. 我在这里做错了导致上述错误的是什么?查询在没有WHERE子句的情况下正常工作。
  2. 除此之外,我想在DISTINCT方法开始处理结果之前使用order by子句。再一次,我搞砸了使用order by和distinct的语法,我得到了一个错误。
  3. 如何根据表中列的值为此查询实现结果排序?

2 个答案:

答案 0 :(得分:4)

在表达式link != '{}'中,别名link引用,而不是单个列(因为tblData AS link)。

Postgres允许使用表名(或表别名)来引用表的完整行。该错误告诉您无法将完整行与单个数组值进行比较。

你需要这样的东西:

select distinct cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
from data 
where cast(xpath('/Data/Link', xmldata) AS TEXT) <> '{}';

不幸的是,在where子句中不可能使用列别名。如果要避免重复表达式,请使用派生表:

select distinct linkdata 
from (
  select cast(xpath('/Data/Link', xmldata) AS TEXT) as linkdata
  from data 
) t 
where linkdata <> '{}';

但是,由于您只想要单个链接,以下情况可能更好:

select distinct linkdata 
from (
  select (xpath('/Data/Link', xmldata))[1] as linkdata
  from data 
) t 
where linkdata is not null;

xpath()返回一个数组,表达式(xpath(..))[1]获取该数组的第一个元素,如果没有这样的元素,则返回null。也许你的事件希望xpath('/Data/Link/UUID/text()')只获得实际的UUID,而不是完整的XML节点 - 但是你提供的例子并不清楚。

答案 1 :(得分:0)

当我有一个表名并且缺少字段名时出现此错误。 简单错误。缺少字段名称的奇怪错误消息。