Reputation: 2777
Let's say there's a person
table with the columns name
and age
.
I'm writing a DSL that generates the following SQL:
select *
from (select * from person p1 inner join person p2 on p1.name = p2.name) as pj;
Now, I would like to be able to access p1
and p2
in the outer query, like this:
select *
from (select * from person p1 inner join person p2 on p1.name = p2.name) as pj
where p1.name = 'xxx'; <-- DOESN'T WORK
Something like pj.p1.name
would be ideal. Is there a way to achieve this if I don't know the exact column names of person
?
Upvotes: 1
Views: 5558
Reputation: 125404
Use using
then just pj.name
or even just name
create table person (id serial, name text);
insert into person (name) values ('John'),('Mary');
select *
from (
select *
from
person p1
inner join
person p2 using(name)
) r
where name = 'John'
;
name | id | id
------+----+----
John | 1 | 1
A clause of the form USING ( a, b, ... ) is shorthand for ON left_table.a = right_table.a AND left_table.b = right_table.b .... Also, USING implies that only one of each pair of equivalent columns will be included in the join output, not both.
If only one side of the join
is necessary:
select *
from (
select p1.*
from
person p1
inner join
person p2 using(name)
) r
where name = 'John'
;
id | name
----+------
1 | John
If both join
sides are necessary then use records:
select (p2).id, (p1).name -- or (p2).*, (p1).*
from (
select p1, p2
from
person p1
inner join
person p2 using(name)
) r
where (p1).name = 'John'
;
id | name
----+------
1 | John
Upvotes: 2
Reputation: 12309
Fetch Extra Column give proper alias name to it
select *
from (select *,
p1.name as pjName --Added Column and use this in where clause
from person p1
inner join person p2 on p1.name = p2.name) as pj
where pjName = 'xxx';
Upvotes: 2
Reputation: 36513
The aliases p1
and p2
are not in scope in the join condition. you can only use the pj
alias. What you need to do is to be more explicit in the subquery about which columns you are selecting, rather than simply doing SELECT * ...
:
Something like:
select *
from (select p1.name, <add other required columns here> -- explicitly select one of the name columns here
from person p1
inner join person p2
on p1.name = p2.name) as pj
where pj.name = 'xxx' -- use pj alias here.
Upvotes: 2