unnest() 子查询返回一个数组?

Dan*_*hin 5 sql database arrays postgresql

unnesting 数组结果返回FROMsub-时,我遇到了一个相当不直观的行为SELECT

SELECT unnest(c).* 
FROM (SELECT chat_messages[0 : array_length(chat_messages, 1)] 
      FROM Chats WHERE chat_id = 2) c
Run Code Online (Sandbox Code Playgroud)

这是我最初的查询。Postgres 不喜欢它:

函数 unnest(record) 不存在

但是这个看似等效的查询有效:

SELECT * 
FROM unnest((SELECT chat_messages[0 : array_length(chat_messages, 1)] 
             FROM Chats WHERE chat_id = 2)) c
Run Code Online (Sandbox Code Playgroud)

此查询对相同的错误消息不起作用:

SELECT * 
FROM (SELECT chat_messages[0 : array_length(chat_messages, 1)] 
      FROM Chats WHERE chat_id = 2) c,
     unnest(c) u
Run Code Online (Sandbox Code Playgroud)

我很确定我在这里遗漏了一些东西。为什么会有这样的行为?record当定义复合类型时,子查询如何返回类型?

kli*_*lin 4

在第一个和第三个查询中,c形式上是一组行(伪类型记录),因此您不能取消嵌套(c)。您应该使用一个值来代替(我跳过了切片,因为不相关):

查询#1:

SELECT (unnest(val)).* 
FROM (
    SELECT chat_messages
    FROM Chats WHERE chat_id = 2
    ) c(val);

-- or

SELECT (unnest(val)).* 
FROM (
    SELECT chat_messages val
    FROM Chats WHERE chat_id = 2
    ) c;
Run Code Online (Sandbox Code Playgroud)

查询#3:

SELECT * 
FROM (
    SELECT chat_messages
    FROM Chats WHERE chat_id = 2
    ) c(val),
    unnest(val) u;

-- or

SELECT * 
FROM (
    SELECT chat_messages val
    FROM Chats WHERE chat_id = 2
    ) c,
    unnest(val) u;
Run Code Online (Sandbox Code Playgroud)

在查询 #2 中,您通过使用附加括号提取一个值,因此结果不是一行而是一个值(在本例中是一个数组)。如果内部查询返回多于一行,则此查询将引发错误。