带有横向连接的查询返回带括号的值。如何删除它?
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
我正在将 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