2010-02-18 4 views
0

Cette requête semble bien fonctionner:SQL: Sélectionnez tout dans une table pas dans une sous-requête?

-- 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"); 

Pour le vérifier, j'aimerais regarder tous les SID qui ne sera pas retourné par cette requête, pour vous assurer qu'ils ne produisent pas de pièces vertes ou rouges . Comment puis-je faire ceci?

Cela ne semble pas fonctionner:

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 Erreur:

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

Quelle est la bonne façon de faire à ce sujet?

C'est le SQL utilisé pour créer les tables avec lesquels je travaille:

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; 

Répondre

5

PAs com En sachant exactement ce que vous obtenez, je vois un certain nombre de choses qui ne vont pas. Tout d'abord enlever la deuxième colonne INTHE sous-requête, il est inutile:

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") 
    ); 

Enfin, vous apear avoir une jointure croisée que je supect vous ne voulez pas. Ceci est un exemple classique de la raison pour laquelle vous ne devez pas utiliser de jointures implicites. Voir si cela pourrait fonctionner mieux:

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 pour attraper des erreurs supplémentaires :) –

+0

+1 pour le commentaire de jointures implicite –

1

Changer votre sous-requête pour retourner une colonne.

ancien sous-requête

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" 

nouvelle sous-requête

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

Les besoins de sélection internes à ne retourner l'id

supprimer: , 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") 
); 
Questions connexes