连接表的 SQL 别名

Posted

技术标签:

【中文标题】连接表的 SQL 别名【英文标题】:SQL Alias of joined tables 【发布时间】: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 中最常被误解的方面之一,仅此而已:) 不用担心,我的问题在逻辑上并不完全合理,所以我知道你怎么能把它当作我自己对这个概念的误解。我认为我修改后的问题是有道理的。 【参考方案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 中的所有记录,直到我意识到在这种情况下它并没有真正意义。不过,我觉得可能存在这样一种情况,即我想在执行外连接后检查约束,我认为任何解决方案都不能解决这个问题。也许这种情况根本不存在。

以上是关于连接表的 SQL 别名的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL 视图中的列选择中使用左连接别名

sql 中如何用别名作为查询条件

sql查询语句学习,多表查询和子查询以及连接查询

MySQL学习笔记连接子分页联合查询以及sql语句执行顺序总结

SQL语句优化系列一

java实现多表的自定义查询。