例如,我有以下关系。
Suppliers( sid: integer, sname: string, address: string)
Parts(pid: integer, pname: string, color: string)
Catalog( sid: integer, pid: integer, cost: real)
我编写以下MYSQL查询以查找仅提供红色部件的供应商的sids。
示例1)
SELECT DISTINCT C.sid FROM Catalog C
WHERE C.sid NOT IN(
SELECT C.sid FROM Catalog C
INNER JOIN Parts P ON p.pid = C.pid
WHERE P.color <> "red"
);
示例2)
SELECT DISTINCT C.sid FROM Catalog C
WHERE C.sid NOT IN(
SELECT C2.sid FROM Catalog C2
INNER JOIN Parts P ON p.pid = C2.pid
WHERE P.color <> "red"
);
我想知道是否有任何不同的赌注。以上两个查询语句。如果我想在嵌套查询中重复使用同一个表两次,我是否必须以不同方式命名我的表别名?我假设内部查询首先在外部查询之前执行,因此示例1应该是正确的,但我无法确定,因为示例2是教授教授的方式。
答案 0 :(得分:1)
您的两个查询之间没有区别。它们完全一样。唯一的区别是您在表Catalog
上使用了不同的别名。解析器将从大多数内部到外部解析别名,因此在查询示例1
SELECT DISTINCT C.sid FROM Catalog C
WHERE C.sid NOT IN(
SELECT C.sid FROM Catalog C
INNER JOIN Parts P ON p.pid = C.pid
WHERE P.color <> "red"
);
来自别名Catalog
的子查询中的C
与外部查询不同。因为解析器将解析它,就像它是另一个表一样。
无论您使用何种别名,解析器都会从内部(子查询)解析为超出。希望你有所了解。
虽然依赖于您使用的运算符,但您可以在子查询中使用外部别名。像下面的查询一样。
要解决您的问题,您可以使用NOT EXISTS子句连接外表,如下所示:
SELECT DISTINCT C.sid
FROM Catalog C
WHERE NOT EXISTS (
SELECT 1
FROM Catalog Cin
INNER JOIN Parts P ON p.pid = Cin.pid
WHERE P.color <> 'red'
AND Cin.sid=C.sid );
答案 1 :(得分:1)
您的查询都有效。如果您想在没有子查询的情况下执行此操作,请尝试以下操作:
select c.sid
from Catalog c inner join Parts p on p.pid = c.sid
group by c.sid
having min(p.color) = 'red' and max(p.color) = 'red'
或
having count(case when p.color = 'red' then 1 else null end) = count(*)
如果您感兴趣,还有另一种方法。它可以让您轻松地一次性获取所有供应商信息:
select *
from Suppliers s
where 'red' = all (
select p.color
from Catalog c inner join Parts p on p.pid = c.pid
where c.sid = s.sid
)
答案 2 :(得分:0)
实际上你并不需要在这种情况下不使用。你的答案接近你的答案。请尝试以下查询;
select c.sid from Catalog as c
inner join Parts as p on c.pid=p.pid
WHERE P.color <> "red"
group by c.sid