如果记录包含所有子查询结果,请选择记录

时间:2016-11-14 18:38:56

标签: sql oracle plsql

我正在尝试创建一个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'

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

1 个答案:

答案 0 :(得分: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