连接表的 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 别名的主要内容,如果未能解决你的问题,请参考以下文章