简体   繁体   中英

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:

column reference "id0" is ambiguous

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"

How do I return just the id0 column from the above query?

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).

True, this way you cannot use SELECT * , but you shouldn't do that anyway. 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 * . 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.

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 *

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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