我真的不认为子查询和半连接是类似的东西。子查询没有什么比在另一个查询中使用的查询更有趣的了:
select * -- this is often called the "outer" query
from (
select columnA -- this is the subquery inside the parentheses
from mytable
where columnB = 'Y'
)
半连接是基于连接的概念。当然,连接表将组合两个表并根据连接条件返回组合的行。从那里,您可以根据进一步的 where 条件(当然还有您想做的任何其他事情)从任一表中选择您想要的列。半连接的概念是当您希望仅从第一个表中返回行,但您需要第二个表来决定要返回哪些行。示例:您想返回班级中的人:
select p.FirstName, p.LastName, p.DOB
from people p
inner join classes c on c.pID = p.pID
where c.ClassName = 'SQL 101'
group by p.pID
这就完成了半连接的概念。我们只返回第一个表(人员)中的列。使用 group by 对于半连接的概念是必要的,因为真正的连接可以从第一个表返回重复的行(取决于连接条件)。上面的例子通常不被称为半连接,也不是最典型的实现方式。以下查询是完成半联接的更常见方法:
select FirstName, LastName, DOB
from people
where pID in (select pID
from class
where ClassName = 'SQL 101'
)
这里没有正式的加入。但是我们使用第二个表来确定要返回第一个表中的哪些行。这很像说如果我们确实将第二个表连接到第一个表,第一个表中的哪些行会匹配?
就性能而言,exists 通常是首选:
select FirstName, LastName, DOB
from people p
where exists (select pID
from class c
where c.pID = p.pID
and c.ClassName = 'SQL 101'
)
在我看来,这是理解半连接最直接的方式。仍然没有正式的连接,但是您可以看到连接的想法,它通过直接匹配第一个表的 pID 列与第二个表的 pID 列的用法来暗示。
最后说明。上面的最后 2 个查询每个都使用一个子查询来完成半连接的概念。