有三个表是这样的:
S (sid, sname, scity)
P (pid, pname, color, weight)
SP (sid, pid, quantity)
问题是返回那些具有蓝色所有 pid 的 sname(s(
起初我写了这个:
SELECT S.sname FROM S INNER JOIN SP ON S.sid = SP.sid
INNER JOIN P ON SP.pid = P.pid
WHERE color = 'blue';
这当然是不对的,因为它返回那些 sname,即使它只有一个蓝色的 P。
我的第二个问题是这个:
SELECT S.sname FROM S INNER JOIN SP ON S.snum = SP.snum
INNER JOIN P ON SP.pnum = P.pnum
WHERE SP.pnum IN
(SELECT pnum FROM P WHERE color != 'blue');
这也是不对的,因为似乎IN
运算符的行为就像多个OR
条件。 你能告诉我如何设置一个条件而不是OR
,就像AND
一样吗?
问题是返回那些具有蓝色所有 pid 的 sname(s(
我想你想要group by
和having
. 我认为这就是你想要的:
select sp.sid
from sp join
p
on sp.pid = p.pid
where p.color = 'blue'
group by sp.sid
having count(distinct sp.pid) = (select count(*) from p p2 where p2.color = 'blue');
这将返回sid
。 您可以使用额外的joi
n 获取名称。
我在戈登的答案中添加了WHERE P.pnum = ANY (SELECT pnum FROM P WHERE color = 'blue')
,当然还添加了另一个join
。 因此,完整的查询是非常适合该问题的查询。
SELECT S.sname
FROM S INNER JOIN SP ON
S.snum = SP.snum
INNER JOIN P ON
SP.pnum = P.pnum
WHERE P.pnum = ANY (SELECT pnum FROM P WHERE color = 'blue')
GROUP BY S.sname
HAVING COUNT(DISTINCT SP.pnum)
=
(SELECT COUNT(*) FROM P WHERE color = 'blue');