带有横向连接的查询返回带括号的值。如何删除它?

Query with lateral join is returning a value with parenthesis. How to remove it?

我正在将 Postgres 用于聊天应用程序。我有两个 table,一个包含对话 ID 和参与者,另一个 table 包含消息。

我运行以下查询来获取用户的所有对话,我使用横向连接将最后一条消息包含在结果中:

select c.id, c.title, c.members, max(m.created_at) delivered_at, last_message
from conversations c
join messages m on c.id = m.conversation_id
left join lateral (select message from messages m where c.id = m.conversation_id order by created_at desc limit 1) last_message on true 
where array[4] <@ c.members 
group by c.id, last_message
order by delivered_at desc

有效,但消息返回为 (message) 而不是 message

我不知道为什么,真的。有什么我可以做的,这样我就不必将括号替换为额外的步骤吗?

您需要在 select 列表中提及列名,而不是 table 名称或别名:

select c.id, c.title, c.members, max(m.created_at) delivered_at, last_message
from conversations c
join messages m on c.id = m.conversation_id
left join lateral (select message from messages m where c.id = m.conversation_id order by created_at desc limit 1) as t(last_message) on true 
where array[4] <@ c.members 
group by c.id, last_message
order by delivered_at desc

解释:

在 PostgreSQL 中,对查询中 table 名称(或别名)的引用实际上是对 table 当前行的复合值的引用。例如,如果我们有如上所示的 table inventory_item,我们可以这样写:

SELECT c FROM inventory_item c;

此查询生成单个复合值列,因此我们可能会得到如下输出:

      c
------------------------
 ("fuzzy dice",42,1.99)

(1 row)

但是请注意,简单名称与 table 名称之前的列名称相匹配,因此此示例之所以有效,只是因为在查询的 table 中没有名为 c 的列。

普通的限定列名语法 table_name.column_name 可以理解为将字段 selection 应用于 table 当前行的复合值。 (出于效率原因,实际上并没有那样实现。)

当我们写作时

SELECT c.* FROM inventory_item c;

那么,按照SQL的标准,我们应该将table的内容展开成单独的列:

name supplier_id price
fuzzy dice 42 1.99
(1 row)

就好像查询是

SELECT c.name, c.supplier_id, c.price FROM inventory_item c;

引自下方link: https://www.postgresql.org/docs/current/rowtypes.html#ROWTYPES-USAGE