【问题标题】:SQL Alias of joined tables连接表的 SQL 别名
【发布时间】:2011-05-03 13:59:04
【问题描述】:

我有一个这样的查询:

select a1.name, b1.info 
 from (select name, id, status 
         from table1 a) as a1
right outer join (select id, info 
                    from table2 b) as b1 on (a1.id = b1.id)

我只想包含 a1.status=1 的所有内容,并且由于我使用的是外连接,因此我不能只向 table1 添加where 约束,因为我想排除来自 table2 的所有信息仍然会在那里,只是没有名字。我在想这样的事情:

 select z1.name, z1.info 
   from ((select name, id, status 
            from table1 a) as a1
right outer join (select id, info 
                    from table2 b) as b1 on (a1.id = b1.id)) as z1 
  where z1.status = 1

但我认为这不合法。

编辑: 如下所述,外部连接实际上对我想要做的事情没有意义。例如,如果我想要 table1 中 status!=1 的 table2 中的所有数据,包括 table1 中根本不存在相应 ID 的所有数据。因此,我需要对 table2 中的所有数据进行外部连接,但仍想排除那些 status=1 的条目。

等价于:

 select z1.name, z1.info 
   from ((select name, id, status 
            from table1 a) as a1
right outer join (select id, info 
                    from table2 b) as b1 on (a1.id = b1.id)) as z1 
  where z1.status != 1

【问题讨论】:

  • 我想我意识到了我的问题......外部连接对我正在做的事情没有任何意义。如果状态需要为 1,则意味着该记录必须存在于 table1 中,所以无论如何我都应该使用内连接。
  • @Lincecum - 回应您的一些 cmets - 我认为您不了解 JOIN 的工作原理。 LEFT OUTER JOIN 显示第一个表中的所有记录,然后显示第二个表中的任何匹配记录(或 NULL,如果没有匹配项)。 RIGHT OUTER JOIN 则相反 - 表 2 中的所有记录,仅在表 1 中匹配。INNER JOIN 仅显示条件匹配/记录存在于两个表中的位置。
  • 实际上,我很清楚 Join 的作用。我最初使用正确的外连接从 table2 中获取所有数据,以确保无论 table1 中是否存在相应的 ID,我都能获得所有数据。从那以后,我决定只需要那些活跃的人的数据,这由 table1 的状态指示。我试图进行此修改,但没有意识到如果 table1 中必须存在具有活动状态的相应记录,则外部连接将变得毫无意义。
  • @Lincecum - 超级,如果我遇到这种情况,我并不是要居高临下或侮辱。连接是 SQL 中最常被误解的方面之一,仅此而已:)
  • 不用担心,我的问题在逻辑上并不完全合理,所以我知道你怎么能把它当作我自己对这个概念的误解。我认为我修改后的问题是有道理的。

标签: sql sql-server join alias outer-join


【解决方案1】:
SELECT a1.Name, b1.Info
FROM table2 b1
    JOIN table2 a1 ON b1.id= a1.id AND a1.status = 1

右外连接与左外连接做同样的事情,只是交换了表。您可以对连接进行过滤,它仍会包含初始表中的数据。

【讨论】:

    【解决方案2】:

    where 子句添加到subquery,如下所示:

    select a1.name, b1.info from
    (
        select name, id
        from table1 a  
        where a.status = 1
    ) as a1
    
    right outer join
    
    (
        select id, info 
        from table2 b
    ) as b1 on (a1.id=b1.id)
    

    【讨论】:

      【解决方案3】:
      select a1.name, b1.info from
      (select name, id, status from table1 a WHERE status=1) as a1
      right outer join
      (select id, info from table2 b) as b1 on (a1.id=b1.id)
      

      编辑:

      对于您的第二种情况:

      select a1.name, b1.info from
      (select name, id, status from table1 a) as a1
      right outer join
      (select id, info from table2 b) as b1 on (a1.id=b1.id)
      EXCEPT
      select a1.name, b1.info from
      (select name, id, status from table1 a WHERE status<>1) as a1
      right outer join
      (select id, info from table2 b) as b1 on (a1.id=b1.id)
      

      这应该可行,因为无论如何您都将获得所有 table2 数据。

      编辑 2:

      好的,要从表 2 中获取所有内容,除了表 1 中有状态 ID,即使表 1 中没有条目,您也需要使用 EXCEPT 函数,该函数基本上会从较大的子集中排除一个子集数据集。

      【讨论】:

      • 见上文。由于这是一个外部连接,所以这不起作用。它实际上不会排除从 table2 中提取的所有内容。
      • 是否还有其他原因需要在此而不是左侧或内部执行 RIGHT OUTER JOIN?在大多数情况下,几乎不需要RIGHT JOIN
      • 不是真的,只要是外连接就可以了
      • 将其设为 LEFT OUTER JOIN 并解决问题,除非您需要 table2 中的孤立记录。
      • 我最初确实想要 table2 中的所有记录,直到我意识到在这种情况下它并没有真正意义。不过,我觉得可能存在这样一种情况,即我想在执行外连接后检查约束,我认为任何解决方案都不能解决这个问题。也许这种情况根本不存在。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多