【问题标题】:Reference alias in subquery子查询中的引用别名
【发布时间】:2016-12-17 01:59:54
【问题描述】:

假设有一个person 表,其中包含nameage 列。

我正在编写一个生成以下 SQL 的 DSL:

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

现在,我希望能够在外部查询中访问 p1p2,如下所示:

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

pj.p1.name 这样的东西是理想的。如果我不知道person 的确切列名,有没有办法做到这一点?

【问题讨论】:

    标签: sql postgresql join subquery


    【解决方案1】:

    使用using,然后只使用pj.name,甚至只使用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
    

    USING (a, b, ...) 形式的子句是 ON left_table.a = right_table.a AND left_table.b = right_table.b ... 的简写。此外,USING 意味着每个子句中只有一个连接输出中将包含一对等效列,而不是两者。

    如果只需要join 的一侧:

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

    如果join 双方都需要,则使用记录:

    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
    

    【讨论】:

    • 不幸的是ERROR: column reference "name" is ambiguous
    • 就是这样!不知道记录,这解决了它。
    【解决方案2】:

    别名 p1p2 不在连接条件的范围内。您只能使用 pj 别名。您需要做的是在子查询中更明确地说明您正在选择哪些列,而不是简单地做SELECT * ...:

    类似:

    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.
    

    【讨论】:

    • 有没有办法包含所有列,即使我不知道它们的名称/数量? IE。某种方式将所有列从 p1 重命名为 p1_* 并等效于 p2?
    • 我不知道。对不起。
    【解决方案3】:

    Fetch Extra Column 给它正确的别名

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

    【讨论】:

    • 聪明,这不是一个坏主意:)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-21
    • 1970-01-01
    • 1970-01-01
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多