如果我想在not in子句中两次查询同一个表,我可以使用相同的表别名吗?

时间:2015-10-01 15:50:52

标签: mysql sql database

例如,我有以下关系。

Suppliers( sid: integer, sname: string, address: string)
Parts(pid: integer, pname: string, color: string)
Catalog( sid: integer, pid: integer, cost: real)

我编写以下MYSQL查询以查找仅提供红色部件的供应商的sids。

示例1)

SELECT DISTINCT C.sid FROM Catalog C 
WHERE C.sid NOT IN(
    SELECT C.sid FROM Catalog C 
    INNER JOIN Parts P ON p.pid = C.pid
    WHERE P.color <> "red"
);

示例2)

SELECT DISTINCT C.sid FROM Catalog C 
WHERE C.sid NOT IN(
    SELECT C2.sid FROM Catalog C2 
    INNER JOIN Parts P ON p.pid = C2.pid
    WHERE P.color <> "red"
);

我想知道是否有任何不同的赌注。以上两个查询语句。如果我想在嵌套查询中重复使用同一个表两次,我是否必须以不同方式命名我的表别名?我假设内部查询首先在外部查询之前执行,因此示例1应该是正确的,但我无法确定,因为示例2是教授教授的方式。

3 个答案:

答案 0 :(得分:1)

您的两个查询之间没有区别。它们完全一样。唯一的区别是您在表Catalog上使用了不同的别名。解析器将从大多数内部到外部解析别名,因此在查询示例1

SELECT DISTINCT C.sid FROM Catalog C 
 WHERE C.sid NOT IN(
              SELECT C.sid FROM Catalog C
                        INNER JOIN Parts P ON p.pid = C.pid
                WHERE P.color <> "red"
             );

来自别名Catalog的子查询中的C与外部查询不同。因为解析器将解析它,就像它是另一个表一样。

无论您使用何种别名,解析器都会从内部(子查询)解析为超出。希望你有所了解。

虽然依赖于您使用的运算符,但您可以在子查询中使用外部别名。像下面的查询一样。

要解决您的问题,您可以使用NOT EXISTS子句连接外表,如下所示:

SELECT DISTINCT C.sid 
  FROM Catalog C 
 WHERE NOT EXISTS (
        SELECT 1 
          FROM Catalog Cin 
                 INNER JOIN Parts P ON p.pid = Cin.pid
         WHERE P.color <> 'red'
           AND Cin.sid=C.sid );

答案 1 :(得分:1)

您的查询都有效。如果您想在没有子查询的情况下执行此操作,请尝试以下操作:

select c.sid
from Catalog c inner join Parts p on p.pid = c.sid
group by c.sid
having min(p.color) = 'red' and max(p.color) = 'red'

having count(case when p.color = 'red' then 1 else null end) = count(*)

如果您感兴趣,还有另一种方法。它可以让您轻松地一次性获取所有供应商信息:

select *
from Suppliers s
where 'red' = all (
    select p.color
    from Catalog c inner join Parts p on p.pid = c.pid
    where c.sid = s.sid
)

答案 2 :(得分:0)

实际上你并不需要在这种情况下不使用。你的答案接近你的答案。请尝试以下查询;

select c.sid from Catalog as c
inner join Parts as p on c.pid=p.pid
WHERE P.color <> "red"
group by c.sid