简体   繁体   English

从带有postgres联接的子查询中选择歧义列

[英]Selecting ambiguous column from subquery with postgres join inside

I have the following query: 我有以下查询:

select x.id0 
from (
  select * 
  from sessions 
     inner join clicked_products on sessions.id0 = clicked_products.session_id0 
) x;

Since id0 is in both sessions and clicked_products , I get the expected error: 由于id0sessionsclicked_products中都clicked_products ,因此出现了预期的错误:

column reference "id0" is ambiguous 列引用“ id0”不明确

However, to fix this problem in the past I simply needed to specify a table. 但是,过去要解决此问题,我只需要指定一个表即可。 In this situation, I tried: 在这种情况下,我尝试:

select sessions.id0 
from (
   select * 
   from sessions 
     inner join clicked_products on sessions.id0 = clicked_products.session_id0 
) x;

However, this results in the following error: 但是,这导致以下错误:

missing FROM-clause entry for table "sessions" 表“会话”缺少FROM子句条目

How do I return just the id0 column from the above query? 如何id0上述查询返回id0列?

Note: I realize I can trivially solve the problem by getting rid of the subquery all together: 注意:我意识到我可以通过完全摆脱子查询来简单地解决问题:

select sessions.id0 
from sessions 
  inner join clicked_products on sessions.id0 = clicked_products.session_id0;

However, I need to do further aggregations and so do need to keep the subquery syntax. 但是,我需要进行进一步的聚合,因此也需要保留子查询语法。

The only way you can do that is by using aliases for the columns returned from the subquery so that the names are no longer ambiguous. 唯一的方法是对子查询返回的列使用别名,以使名称不再歧义。

Qualifying the column with the table name does not work, because sessions is not visible at that point (only x is). 用表名限定列不起作用,因为此时sessions不可见(只有x是可见的)。

True, this way you cannot use SELECT * , but you shouldn't do that anyway. 没错,这种方式不能使用SELECT * ,但是无论如何都不应该这样做。 For a reason why, your query is a wonderful example: 由于某种原因,您的查询是一个很好的示例:
Imagine that you have a query like yours that works, and then somebody adds a new column with the same name as a column in the other table. 假设您有一个像您这样的查询,并且该查询有效,然后有人添加了一个与其他表中的列同名的新列。 Then your query suddenly and mysteriously breaks. 然后,您的查询突然神秘地中断。

Avoid SELECT * . 避免SELECT * It is ok for ad-hoc queries, but not in code. 临时查询是可以的,但在代码中不行。

I assume: 我假设:

select x.id from (select sessions.id0 id
  from sessions 
  inner join clicked_products 
  on sessions.id0 = clicked_products.session_id0 ) x;

should work. 应该管用。

Other option is to use Common Table Expression which are more readable and easier to test. 另一种选择是使用通用表表达式 ,它更具可读性并且更易于测试。 But still need alias or selecting unique column names. 但是仍然需要别名或选择唯一的列名。

In general selecting everything with * is not a good idea -- reading all columns is waste of IO. 通常,用*选择所有内容不是一个好主意-读取所有列会浪费IO。

select x.id from
 (select sessions.id0 as id, clicked_products.* from sessions
 inner join
 clicked_products on
 sessions.id0 = clicked_products.session_id0 ) x;

However, you have to specify other columns from the table sessions since you cannot use SELECT * 但是,由于不能使用SELECT *,因此必须从表会话中指定其他列。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM