Mysql查询用作子查询时会产生不同的结果

Mysql查询用作子查询时会产生不同的结果,mysql,correlated-subquery,Mysql,Correlated Subquery,我在Mysql中使用以下代码定义了表PARTS、CATALOG和PLIST: create table parts ( PID int ); create table catalog( SID varchar(3), PID int ); create table plist( PID int ); insert into parts values (1),(2),(3), (4); insert into catalog values ("A", 1), ("A", 2),

我在Mysql中使用以下代码定义了表PARTS、CATALOG和PLIST:

create table parts (
  PID int
);
create table catalog(
  SID varchar(3),
  PID int
);
create table plist(
  PID int
);
insert into parts values (1),(2),(3), (4);
insert into catalog values
  ("A", 1), ("A", 2), ("A", 4),
  ("B", 2), ("B", 3), ("B", 4),
  ("C", 1), ("C", 4),
  ("D", 2), ("D", 3);
insert into plist values (2), (4);
我想执行关系除法运算符catalog plist。关系除法运算符在SQL中不可用。以下实现在Oracle中成功运行:

SELECT DISTINCT(SID) FROM CATALOG A WHERE NOT EXISTS
    (SELECT PID FROM PLIST MINUS SELECT PID FROM CATALOG WHERE SID = A.SID);
现在,在MYsql中,减号运算符不可用。下面的查询在Mysql中成功地实现了上面使用的减号操作(引入了一个独立测试查询的修改)

SELECT B.PID FROM PLIST LEFT JOIN 
  (SELECT PID FROM CATALOG  WHERE SID = "C") B ON B.PID=PLIST.PID 
  WHERE B.PID IS NULL; 
但是,当我使用上述代码作为子查询来实现关系分割运算符时

SELECT DISTINCT(SID) FROM CATALOG WHERE NOT EXISTS 
  ( SELECT B.PID FROM PLIST LEFT JOIN 
      (SELECT A.PID FROM CATALOG A WHERE A.SID = SID) B ON B.PID = PLIST.PID
      WHERE B.PID IS NULL
);
我没有得到预期的结果。预期结果仅包含SID值“A”和“B”。但是,上述代码生成的结果包含所有四个SID值。这很奇怪,因为当独立测试时,子查询会生成正确的结果(如果SID等于“A”或“B”,则为空,对于SID的其他两个值,则为非空)

如果这个论坛上有人能解释这种奇怪的行为,我将不胜感激


非常感谢。该行为解释如下:

我编写的查询是错误的,因为在内部查询中,A.SID和SID之间没有区别。因此,该条件总是导致TRUE

因此,作为相关子查询的目的实际上并非如此

这解释了为什么查询结果包含所有四个SID

但是,正如我在第一条注释中所述,当我在外部查询中为表使用别名,并在内部查询中使用该别名时,如下所示

SELECT DISTINCT(SID) FROM CATALOG A WHERE NOT EXISTS 
  ( SELECT B.PID FROM PLIST LEFT JOIN 
      (SELECT PID FROM CATALOG WHERE SID = A.SID) B ON B.PID = PLIST.PID
      WHERE B.PID IS NULL
);
我得到错误:where子句中的未知列“A.SID”


我不明白为什么别名A不在子查询的范围内。

该行为解释如下:

我编写的查询是错误的,因为在内部查询中,A.SID和SID之间没有区别。因此,该条件总是导致TRUE

因此,作为相关子查询的目的实际上并非如此

这解释了为什么查询结果包含所有四个SID

但是,正如我在第一条注释中所述,当我在外部查询中为表使用别名,并在内部查询中使用该别名时,如下所示

SELECT DISTINCT(SID) FROM CATALOG A WHERE NOT EXISTS 
  ( SELECT B.PID FROM PLIST LEFT JOIN 
      (SELECT PID FROM CATALOG WHERE SID = A.SID) B ON B.PID = PLIST.PID
      WHERE B.PID IS NULL
);
我得到错误:where子句中的未知列“A.SID”


我不明白为什么别名A不在子查询的范围内。

我在内部查询中使用了别名A作为目录表,而不是将其用于外部查询,因为Mysql无法识别用于外部查询的别名。我还知道另一种在操作中使用减号的实现,我可以成功地将其用于在Mysql中实现关系除法。我在内部查询中的目录表中使用了别名A,而不是将其用于外部查询,因为Mysql无法识别用于外部查询的别名。我还知道另一种在操作中使用减号的实现,我可以成功地使用它在Mysql中实现关系除法。