我有两个看起来像这样的表:
SN SNAME Stat City
+----------+-------+----+--------+
| S1 | Smith | 20 | London |
| S2 | Jones | 10 | Paris |
| S3 | Blake | 30 | Paris |
| S4 | Clark | 20 | London |
| S5 | Adams | 30 | Athens |
+----------+-------+----+--------+
SN PN QTY
+----+----+-----+
| S1 | P1 | 300 |
| S1 | P2 | 200 |
| S1 | P3 | 400 |
| S1 | P4 | 200 |
| S1 | P5 | 100 |
| S1 | P6 | 100 |
| S2 | P1 | 300 |
| S2 | P2 | 400 |
| S3 | P2 | 200 |
| S4 | P2 | 200 |
| S4 | P4 | 300 |
| S4 | P5 | 400 |
+----+----+-----+
我找到了以下内容:
列出供应商S2提供的至少所有零件(PN)的供应商的供应商名称(SNAME)。
换句话说,我需要列出所有那些至少发货P1和P2的供应商,但显然我的查询需要更多地关注手头的问题。
我很确定我必须使用某种形式的NOT EXISTS - 也许双重不存在,才能实现这一点。我尝试将Shipment表自行连接到自身 - 但我无法理解除了检查出现在PN for S2中的任何项目之外如何检查它,而是检查以确保S2的所有部分都在在结果中包含名称之前列出。
答案 0 :(得分:1)
您是否可以使用嵌套的select语句来优化结果?
例如:
SELECT SNAME FROM Supplier
INNER JOIN Shipment ON Supplier.SN = Shipment.SN
WHERE Shipment.PN IN (SELECT PN FROM Shipment WHERE SN = S2)
这样,部件(PN)仅限于S2销售的部件。
已编辑将语句更改为
Shipment.PN IN (SELECT PN FROM Shipment WHERE SN = S2)
现在,即使他们卖掉了其中的一件,只有当他们卖出至少 S2销售的东西时,他们才会被退回。
答案 1 :(得分:1)
我使用Common Table Expression来实现这一目标:
--CTE will contain records from the Supplier you are looking to check against
WITH desiredSN AS
(
SELECT s.SN, s.PN
FROM Shipment AS s
WHERE s.SN = 'S2'
)
--SELECT will join all other shippers with each record of your Supplier S2 here
SELECT s.SN
FROM Shipment AS s
INNER JOIN desiredSN AS d ON s.PN = d.PN
WHERE s.SN != 'S2'
GROUP BY s.SN
--Having ensures that the count of your old supplier matches
--the number a potential supplier overlaps with
HAVING COUNT(1) =
(
SELECT COUNT(1)
FROM desiredSN AS d
)
如果您不想使用CTE,则可以使用子查询:
SELECT s.SN
FROM Shipment AS s
INNER JOIN
(
SELECT s.SN, s.PN
FROM Shipment AS s
WHERE s.SN = 'S2'
)
AS d ON s.PN = d.PN
WHERE s.SN != 'S2'
GROUP BY s.SN
HAVING COUNT(1) =
(
SELECT COUNT(1)
FROM Shipment AS s
WHERE s.SN = 'S2'
)