2016-08-10 2 views
1

Nehmen wir an, es gibt eine Tabelle mit den Spalten name und age.Referenz-Alias ​​in der Unterabfrage

ich einen DSL bin zu schreiben, die die folgende SQL erzeugt:

select * 
    from (select * from person p1 inner join person p2 on p1.name = p2.name) as pj; 

Nun würde Ich mag Lage sein, den Zugriff auf p1 und p2 in der äußeren Abfrage, wie folgt aus:

select * 
    from (select * from person p1 inner join person p2 on p1.name = p2.name) as pj 
    where p1.name = 'xxx'; <-- DOESN'T WORK 

Etwas wie pj.p1.name wäre ideal. Gibt es eine Möglichkeit, dies zu erreichen, wenn ich die genauen Spaltennamen von person nicht kenne?

Antwort

2

Verwenden using dann nur pj.name oder auch nur 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.

Wenn nur eine Seite des join notwendig:

select * 
from (
    select p1.* 
    from 
     person p1 
     inner join 
     person p2 using(name) 
) r 
where name = 'John' 
; 
id | name 
----+------ 
    1 | John 

Wenn beide join Seiten notwendig werden dann Datensätze verwenden:

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 
+1

Leider FEHLER: Spaltenreferenz "Name" ist mehrdeutig. –

+1

@PhilipKamenarsky Überprüfen Sie die aktualisierte Antwort –

+0

Das war's! Ich wusste nichts von Aufzeichnungen, das löst es. –

1

Die Aliase p1 und p2 sind nicht in der Join-Bedingung enthalten. Sie können nur den Alias ​​ verwenden. Was Sie tun müssen, ist expliziter in der Unterabfrage zu sein, über die Spalten, die Sie auswählen, sondern einfach als SELECT * ... tun:

Etwas wie:

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. 
+0

Gibt es eine Möglichkeit, alle Spalten einzuschließen, auch wenn ich ihre Namen/Anzahl nicht kenne? I.e. eine Möglichkeit, alle Spalten von 'p1' in' p1_ * 'und äquivalent für' p2' umzubenennen? –

+0

Nicht, dass ich weiß. Es tut uns leid. – sstan

2

zusätzliche Spalte geben richtigen Alias-Namen, um es Fetch

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'; 
+1

Smart, das ist keine schlechte Idee :) – sstan