有人能解释一下sql查询是如何工作的吗?

Aru*_*tel 1 sql database sql-server

下面的 SQL 查询获取所有具有不同姓氏的名字。

select a.first_name
from names a
WHERE a.first_name in (
select b.first_name 
  from names b
  WHERE a.last_name<>b.last_name
)
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚这到底是如何工作的。我认为会发生的是,对于表中的每一行,子查询将检查是否存在具有不同姓氏的行。但检查仅发生在名字的相同值之间。有人可以解释一下这实际上是如何运作的吗?

use*_*983 5

首先,正如我在评论中提到的,我建议使用 a 来代替HAVING。它不需要对表进行 2 次扫描,只需扫描一次,它不会返回相同的重复项first_name,并且您可能更容易理解:

SELECT first_name
FROM dbo.names
GROUP BY first_name
HAVING COUNT(DISTINCT last_name) > 1;
Run Code Online (Sandbox Code Playgroud)

应该是相当不言自明的;它返回的行中的每个值都有超过 1 个不同的值。last_namefirst_name


对于您的查询,让我们看看WHERE

WHERE a.first_name IN (SELECT b.first_name 
                       FROM names b
                       WHERE a.last_name<>b.last_name
Run Code Online (Sandbox Code Playgroud)

names首先,我们“连接” (别名aad )的 2 个实例,其中2 个实例b的值不同。last_name这可能是一项昂贵的操作;如果你有一个包含 1,000 行的表,并且它有 900 个不同的值,last_name那么你最终会得到每数百个匹配的连接。

之后,它检查first_name别名实例中行的值names,如a来自连接的行集中的值;确实如此,那么有 2 个(或更多)first_name具有不同last_name值的相同实例。

在上下文中,将 anIN与子查询一起使用与使用值的文字列表没有什么不同。WHERE SomeColumn IN (1,2,3,4,5,7)就好像表中的WHERE SomeColumn IN (SELECT I FROM SomeTable)列具有值、、、、和一样。ISomeTable123457