[英]What is a better way to write this SQL query?
我有以下关系。
Suppliers( sid: integer, sname: string, address: string)
Parts(pid: integer, pname: string, color: string)
Catalog( sid: integer, pid: integer, cost: real)
这个问题要求我找到Acme Widget Suppliers提供的零件的pnames,而不是其他人。 我写了以下SQL语句; 但是我觉得这个查询由于重复而效率低下。 我想知道是否有更好的方法来编写此查询而不重复选择目录部分。
Select P.pname
FROM Parts P
WHERE P.pid IN (
Select C.pid
FROM Catalog C
INNER JOIN Supplier S
ON S.sid = C.sid
WHERE S.sname = "Acme Widget Suppliers"
AND C.pid NOT IN (
SELECT C2.pid
FROM Catalog C2
INNER JOIN Supplier S
ON S.sid = C2.sid
WHERE S.sname <> "Acme Widget Suppliers"
)
);
我在第二部分使用left join
,因为我希望得到nulls
。 在那种情况下,只有一行为极致而没有其他人
Select *
FROM Parts P
INNER JOIN Catalog C1
ON P.pid = C1.pid
INNER JOIN Suppliers S1
ON C1.sid = S1.sid
LEFT JOIN Catalog C2
ON P.pid = C2.pid
AND C1.sid <> C2.sid
WHERE
S1.sname = 'Acme'
AND C2.sid IS NULL
正确的查询将是:
Select P.PName from Suppliers S1
join Catalog C1
on S1.sid = C1.sid
join parts P
on P.pid = C1.pid
where S1.sname = 'Acme Widget Suppliers'
and not exists
( select 1 from catalog C2 where C2.sid != C1.sid
and C2.pid = C1.pid)
不存在是非常有效的,因为它在找到第一次出现时停止搜索。
我只是尝试将三个表连接在一起,然后使用您已经使用的WHERE
子句进行限制。 我在SELECT
语句中使用了DISTINCT
来确保重复项被删除,如果它们发生的话。
SELECT DISTINCT p.pname
FROM Parts p INNER JOIN Catalog c
ON p.pid = c.pid
INNER JOIN Suppliers s
ON c.sid = s.sid
WHERE s.sname = "Acme Widget Suppliers"
这可以工作:
select p.pname from Catalog c
join Parts p on p.pid = c.pid
join Suppliers s on s.sid = c.sid
where s.sname = 'Acme Widget Suppliers'
and p.pid in (select pid as SupplierCount from Catalog c
group by pid having count(*) = 1)
内部select
旨在寻找任何供应商的独家零件。 如果某个零件由多个供应商销售,则不会包含该零件。
工作示例: http : //sqlfiddle.com/#!6/1ccde/10
为了提供另一种解决这个问题的方法,这里有一个使用数据分组的变体。 这是一个选择由'Acme Widget Suppliers'提供的所有pnames的解决方案
Select P.pname
FROM Parts P
INNER JOIN Catalog C on c.pid=p.pid
INNER JOIN Supplier S ON S.sid = C.sid
GROUP BY p.pname
HAVING min(s.sname)=max(s.sname)
and max(s.name)='Acme Widget Suppliers'
按pname选择组并计算供应商名称的最小值和最大值 。 如果有一个零件的不同供应商最小和最大不相等。
据我所知,问题中的细微差别(部分由'Acme'提供或部分由'Acme'提供而且没有其他人)仍然不清楚,我会坚持后来更难选择;)。
你是对的。 您想要进行的查询可以大大简化。 请尝试以下方法。
SELECT P.pname FROM Parts P, Suppliers S, Catalog C
WHERE C.pid = P.pid
AND C.sid = S.sid
AND S.sname == "Acme Widget Suppliers"
根据你的查询,似乎不是不需要也exists
语句比in
和连接好得多。
Select P.pname
FROM Parts P
WHERE EXISTS (
Select C.pid
FROM Catalog C
INNER JOIN Supplier S
ON S.sid = C.sid
WHERE P.pid = C.pid AND S.sname = "Acme Widget Suppliers"
);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.