2010-02-18 50 views
0

这个查询看起来运行良好:SQL:选择不在子查询中的表中的所有内容?

-- Every supplier that produces some red or green part 
SELECT Suppliers.sid 
FROM Suppliers, Catalog, Parts 
WHERE Suppliers.sid = Catalog.sid 
    AND Catalog.pid = Parts.pid 
    AND (Parts.color = "red" OR Parts.color = "green"); 

要检查它,我想看看这不会受到此查询返回的每一个SID,以确保它们不产生绿色或红色部分。我怎样才能做到这一点?

这似乎并不奏效:

SELECT Parts.color 
FROM Suppliers, Catalog, Parts 
WHERE Suppliers.sid NOT IN ( 
    SELECT Suppliers.sid, Parts.color 
    FROM Suppliers, Catalog, Parts 
    WHERE Suppliers.sid = Catalog.sid 
     AND Catalog.pid = Parts.pid 
     AND (Parts.color = "red" OR Parts.color = "green") 
    ); 

MySQL的错误:

Error 1241 (21000): Operand should contain 1 column(s)

什么是去了解这个正确的方式?

这是用于创建我的工作表上的SQL:

SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0; 
SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0; 
SET @[email protected]@SQL_MODE, SQL_MODE='TRADITIONAL'; 

CREATE SCHEMA IF NOT EXISTS `mydb` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ; 
USE `mydb`; 

-- ----------------------------------------------------- 
-- Table `mydb`.`Suppliers` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`Suppliers` (
    `sid` INT NOT NULL , 
    `sname` VARCHAR(45) NULL , 
    `address` VARCHAR(45) NULL , 
    PRIMARY KEY (`sid`)) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`Parts` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`Parts` (
    `pid` INT NOT NULL , 
    `pname` VARCHAR(45) NULL , 
    `color` VARCHAR(45) NULL , 
    PRIMARY KEY (`pid`)) 
ENGINE = InnoDB; 


-- ----------------------------------------------------- 
-- Table `mydb`.`Catalog` 
-- ----------------------------------------------------- 
CREATE TABLE IF NOT EXISTS `mydb`.`Catalog` (
    `cost` INT NULL , 
    `pid` INT NOT NULL , 
    `sid` INT NOT NULL , 
    PRIMARY KEY (`pid`, `sid`) , 
    INDEX `fk_Catalog_Parts1` (`pid` ASC) , 
    INDEX `fk_Catalog_Suppliers1` (`sid` ASC) , 
    CONSTRAINT `fk_Catalog_Parts1` 
    FOREIGN KEY (`pid`) 
    REFERENCES `mydb`.`Parts` (`pid`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION, 
    CONSTRAINT `fk_Catalog_Suppliers1` 
    FOREIGN KEY (`sid`) 
    REFERENCES `mydb`.`Suppliers` (`sid`) 
    ON DELETE NO ACTION 
    ON UPDATE NO ACTION) 
ENGINE = InnoDB; 



SET [email protected]_SQL_MODE; 
SET [email protected]_FOREIGN_KEY_CHECKS; 
SET [email protected]_UNIQUE_CHECKS; 

回答

5

不COM完全知道你在得到什么,我发现一些错误的东西。首先拆下在矿井子查询中的第二列,这是不必要的:

SELECT Parts.color 
FROM Suppliers, Catalog, Parts 
WHERE Suppliers.sid NOT IN (  
    SELECT Suppliers.sid FROM Suppliers, Catalog, Parts 
    WHERE Suppliers.sid = Catalog.sid 
     AND Catalog.pid = Parts.pid 
     AND (Parts.color = "red" OR Parts.color = "green") 
    ); 

最后你apear有一个交叉连接,我supect你不想。这是为什么你不应该使用隐式连接的典型例子。看看这可能会更好地工作:

SELECT Parts.color 
FROM Suppliers 
JOIN Catalog on Suppliers.sid = Catalog.sid 
JOIN Parts on Catalog.pid = Parts.pid 
WHERE Suppliers.sid NOT IN (  
    SELECT Suppliers.sid 
    FROM Suppliers 
    JOIN Catalog on Suppliers.sid = Catalog.sid 
    JOIN Parts on Catalog.pid = Parts.pid 
     WHERE (Parts.color = "red" OR Parts.color = "green") 
    ); 
+0

+ 1为捕捉更多的错误:) – 2010-02-18 22:53:28

+0

+1为隐式联接评论 – 2010-02-18 22:54:03

1

改变你的子查询返回一列。

旧子查询

SELECT Suppliers.sid, Parts.color 
    FROM Suppliers, Catalog, Parts 
    WHERE Suppliers.sid = Catalog.sid 
     AND Catalog.pid = Parts.pid 
     AND (Parts.color = "red" OR Parts.color = "green" 

新的子查询

SELECT Suppliers.sid 
    FROM Suppliers, Catalog, Parts 
    WHERE Suppliers.sid = Catalog.sid 
     AND Catalog.pid = Parts.pid 
     AND (Parts.color = "red" OR Parts.color = "green" 
1

内选择需要只返回ID

删除:, Parts.color

SELECT Parts.color 
FROM Suppliers, Catalog, Parts 
WHERE Suppliers.sid NOT IN ( 
SELECT Suppliers.sid 
FROM Suppliers, Catalog, Parts 
WHERE Suppliers.sid = Catalog.sid 
    AND Catalog.pid = Parts.pid 
    AND (Parts.color = "red" OR Parts.color = "green") 
);