我刚开始接触sql,目标是转化这个。
select X.persnr
from Pruefung X
where X.persnr in (
select Y.persnr
from pruefung Y
where X.matrikelnr <> Y.matrikelnr)
output:
转化为相同的输出,但要使用连接的形式。我尝试了下面的方法,但就我所见,似乎无法 "摆脱 "cartesian product。或者也许我误解了上面的声明,它实际上应该做什么。对我来说,上面说的是 "对于每个独特的matrikelnr显示所有对应的persnr"。
select X.persnr
from Pruefung X
join pruefung y on x.persnr=y.persnr
where x.matrikelnr<>y.matrikelnr
输出。一个长长的列表(我不想用它来填满整个问题)--我猜测加入的卡提斯乘积是
这是我使用的关系。
编辑:Distinct(除非我用错了地方)不行,因为这样的话persnr只显示一次,不过这不是目标。
你的初始查询实际上是:select persnr from Pruefung if the same persnr exists for a diferent matrikelnr.
"for each unique matrikelnr display all corresponding persnr "这是通过聚合实现的。
根据你所使用的DBMS,你可以使用类似于(SQL Server使用STRING_AGG,但MySQL使用GROUP_CONCAT)的方法。
SELECT matrikelnr,STRING_AGG(matrikelnr,',')
GROUP BY matrikelnr
你不能通过使用联接来轻松实现你从关联查询(你的第一次尝试)中得到的东西。
编辑:当没有连接条件(CROSS JOIN)时,连接不会产生 "笛卡尔积"。联接是基于联接条件来匹配两个集合。之所以会有更多的条目,是因为联接是根据联接键(PERSNR)来进行匹配的。
例如对于101,你有3个条目。这意味着你将得到3x3的结果.然后你过滤掉X.matrikelnr <> Y.matrikelnr的情况下,如果我们假设matrikelnr是唯一的,这将意味着该行与自己匹配。
如果你想在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
)
这样很明显,这个查询的意思是:
返回所有的
persnr
的表,其中存在另一条相同的记录。persnr
但不同matrikelnr
对于您的样本数据,结果是所有的 persnr
的表。
但你的第2个查询,做了一些不同的事情。它 链接 表的每一行都与同表的所有行有相同的关系。persnr
但不同 matrikelnr
. 因此,对于表中的每一行,你将得到与相同的 persnr
殊途同归 matrikelnr
s. 例如第1行有 persnr = 101
和 matrikelnr = 8532478
你将得到2行,因为在表中有2行与 persnr = 101
和 matrikelnr <> 8532478
.
你是对的. 是卡提斯积的错。假设你在第一个表中有 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)
你自己选吧