为什么这两个 sql 语句不返回相同的输出?

Why aren't these two sql statements returning same output?

我刚刚开始使用 sql 并且有 objective 来转换它:

select X.persnr 
from Pruefung X 
where X.persnr in (
    select Y.persnr 
    from pruefung Y 
    where X.matrikelnr <> Y.matrikelnr)

输出:

进入相同的输出,但使用连接形式。我尝试了下面的方法,但据我所知,我似乎无法获得笛卡尔积的 "rid" 。或者也许我误解了上面的声明它实际上应该做什么。对我来说,上面说 "for each unique matrikelnr display all corresponding persnr"。

select X.persnr 
from Pruefung X 
join pruefung y on x.persnr=y.persnr 
where x.matrikelnr<>y.matrikelnr

输出:一长串(我不想用它来填满整个问题)- 我猜是来自连接的笛卡尔积

这是我正在使用的关系。

编辑:Distinct(除非我在错误的地方使用它)将不起作用,因为 persnr 只显示一次,但那不是 objective。

您的初始查询实际上是: select 来自 Pruefung 的 persnr 如果不同的 matrikelnr 存在相同的 persnr。

"for each unique matrikelnr display all corresponding persnr" 这是使用聚合实现的:

根据您使用的 DBMS,您可以使用类似(SQL 服务器使用 STRING_AGG,但 MySQL 使用 GROUP_CONCAT)

SELECT matrikelnr,STRING_AGG(matrikelnr,',')
GROUP BY matrikelnr

您无法通过使用联接轻松实现从相关查询(您的第一次尝试)中获得的结果。

编辑: 当没有连接条件(CROSS JOIN)时,连接不会导致 "Cartesian product" 期望。 连接根据连接条件匹配两个集合。您获得更多条目的原因是连接查看连接键 (PERSNR) 并进行匹配。

例如,对于 101,您有 3 个条目。这意味着您将获得 3x3 的结果。 然后过滤掉 X.matrikelnr <> Y.matrikelnr 情况下的结果 如果我们假设 matrikelnr 是唯一的,这意味着该行与自身匹配。所以你将失去 3 个结果,结果为 3x3 - 3 = 6.

如果您想在 SQL 中有所作为,您必须首先定义您期望使用的内容,然后使用适当的工具(在这种情况下相关查询不是连接)

您可以使用 EXISTS 而不是 IN 编写第一个查询,例如:

select X.persnr 
from Pruefung X 
where exists (
    select 1 
    from pruefung Y 
    where X.persnr = Y.persnr and X.matrikelnr <> Y.matrikelnr
)

这样很明显这个查询意味着:

return all the persnrs of the table for which there exists another row with the same persnr but different matrikelnr

对于您的示例数据,结果是 table 的所有 persnr

虽然你的第二个查询做了一些不同的事情。
链接 table 的每一行与相同 table 具有相同 persnr 但不同 matrikelnr 的所有行。
因此,对于 table 的每一行,您将获得与相同 persnr 不同 matrikelnr 的行一样多的行。
例如,对于 persnr = 101matrikelnr = 8532478 的第一行,您将得到 2 行,因为 table 中有 2 行 persnr = 101matrikelnr <> 8532478

你是对的。这是笛卡尔积的错。假设第一个 table 中有 persnr 1,1,1,2,2,2,第二个中有 persnr 1,1,1,2,2。您希望返回多少行? 在 pdeuso 代码中它会像这样

Select 
...
WHERE persnr in (second table) 
-- 6 lines

Select persnr
FROM ...
JOIN ... ON a.persnr = b.persnr
-- 3X3 + 3X2 = 15 lines.

SELECT DISTINCT persnr
FROM ...
JOIN ... ON a.persnr = b.persnr
-- 2 lines (1 and 2)

任你选