2016-11-14 29 views
0

我正在尝试创建select语句。我想选择包含子查询中所有记录的记录。如果它们包含所有子查询结果,请选择记录

我有这样一个子查询:

SELECT P.pid 
FROM Parts P 
INNER JOIN Manifacturers M INNER JOIN M.mid ON P.pid 
WHERE M.name = 'Mercedes' 

我要选择的供应商,如果他们出售所有这些部件。我试了几件事:

SELECT s.name 
FROM Suppliers S 
INNER JOIN Parts P1 ON S.pid = P1.pid 
WHERE p1.pid IN (SELECT P.pid 
    FROM Parts P 
    INNER JOIN Manifacturers M INNER JOIN M.mid ON P.pid 
    WHERE M.name = 'Mercedes') 

这显然失败了。这将返回供应商,如果他们有任何部分。其实我设法通过使用INTERSECT得到关闭:

SELECT P1.pid 
FROM Suppliers S 
INNER JOIN Parts P1 ON S.pid = P1.pid 
INTERSECT 
SELECT P.pid 
FROM Parts P 
INNER JOIN Manifacturers M INNER JOIN M.mid ON P.pid 
WHERE M.name = 'Mercedes' 

这将返回正确的pids,但此语法不允许我返回s.name。它不会让我添加第二个查询中不存在的任何字段。

回答

1

你应该尝试使用条件COUNT()

SELECT COUNT(CASE WHEN M.name = 'Mercedes' THEN 1 END) AS total_mercedes 
FROM Parts P 
INNER JOIN Manifacturers M INNER JOIN M.mid ON P.pid 

那么你必须制造具有相同数量的零件。

SELECT s.name, 
     COUNT(CASE WHEN M.name = 'Mercedes' THEN 1 END) AS total_supplier 
FROM Suppliers S 
INNER JOIN Parts P1 ON S.pid = P1.pid 
INNER JOIN Manifacturers M INNER JOIN M.mid ON P.pid 
CROSS JOIN (SELECT COUNT(CASE WHEN M.name = 'Mercedes' THEN 1 END) AS total_mercedes 
      FROM Parts P 
      INNER JOIN Manifacturers M INNER JOIN M.mid ON P.pid 
      ) M 
GROUP BY s.name 
HAVING T.total_mercedes = total_supplier 

另一种选择是与LEFT JOIN

首先你需要梅赛德斯和每个供应商的每个Pid。然后检查是否有任何NULL

SELECT S.name 
FROM (SELECT P.Pid 
     FROM Parts P 
     INNER JOIN Manifacturers M INNER JOIN M.mid ON P.pid 
     WHERE M.name = 'Mercedes' 
    ) M 
CROSS JOIN (SELECT DISTINCT S.name, 
      FROM Suppliers S 
      ) S 
LEFT JOIN Suppliers Sales 
     ON M.Pid = Sales.Pid 
    AND S.name = Sales.Name 
GROUP BY S.name 
HAVING COUNT(CASE WHEN Sales.Pid IS NULL THEN 1 END) = 0 
+0

@Matt修复'CASE'。但没有看到如何简化派生表,你需要有一个与所有零件和供应商的基础,然后做'LEFT JOIN' –

+0

哦,我看到它...起初我使用加入制造商,但实现供应商已经有'Pid'。 –

+0

是的,这不是什么大事,我只是觉得它没有它更干净。好答案 – Matt

相关问题