2010-11-26 56 views
0

J'ai beaucoup de problèmes avec la dernière requête dont j'ai besoin et je pense que c'est un niveau hors de ma ligue donc toute aide est appréciée.Problèmes SQL Query existent

Les tableaux:

CREATE TABLE Recipe 
(
    nrecipe  integer, 
    name   varchar(255), 
    primary key (nrecipe) 
); 

CREATE TABLE Food 
(
    designation varchar(255) unique, 
    quantity  integer, 
    primary key (designation) 
); 

CREATE TABLE Contains 
(
    nrecipe  integer, 
    designation varchar(255), 
    quantity  integer, 
    primary key (nrecipe, designation), 
    foreign key (nrecipe) references Recepie (nrecipe), 
    foreign key (designation) references Food (designation) 
); 

Quantity dans le tableau Food est la quantité stocker dans l'entrepôt.

Quantity en Contains est la quantité nécessaire d'un élément alimentaire à utiliser dans la recette.

Quantity dans Food et Contains diffèrent les uns des autres.

La requête:

Je veux connaître les noms de toutes les recettes qui sont possibles à faire avec la nourriture stockée dans l'entrepôt.

Il faut que la quantité de chaque élément de nourriture dans l'entrepôt soit plus grande que la quantité nécessaire pour la recette.

EDIT: aussi, il ne devrait pas afficher le nom d'une recette s'il n'y a rien qui s'y rapporte sur le tableau Contains.

Pour le rendre plus facile à comprendre, je vais vous donner quelques données:

INSERT INTO Recipe VALUES ('01', 'Steak with potatos and water'); 
INSERT INTO Recipe VALUES ('02', 'Rice and ice tea'); 
INSERT INTO Recipe VALUES ('03', 'Potatos and shrimp'); 
INSERT INTO Recipe VALUES ('04', 'Water'); 
INSERT INTO Recipe VALUES ('05', 'Steak with rice'); 
INSERT INTO Recipe VALUES ('06', 'Steak with spaguetti'); 
INSERT INTO Recipe VALUES ('07', 'Potatos with rice'); 

INSERT INTO Food VALUES ('Water', 5); 
INSERT INTO Food VALUES ('Ice tea', 10); 
INSERT INTO Food VALUES ('Steak', 30); 
INSERT INTO Food VALUES ('Potatos', 20); 
INSERT INTO Food VALUES ('Rice', 50); 
INSERT INTO Food VALUES ('Shrimp', 5); 
INSERT INTO Food VALUES ('Spaguetti', 5); 

INSERT INTO Contains VALUES ('01', 'Steak', 1); 
INSERT INTO Contains VALUES ('01', 'Potatos', 15); 
INSERT INTO Contains VALUES ('01', 'Water', 10); 
INSERT INTO Contains VALUES ('02', 'Rice', 5); 
INSERT INTO Contains VALUES ('02', 'Ice tea', 8); 
INSERT INTO Contains VALUES ('03', 'Potatos', 1); 
INSERT INTO Contains VALUES ('03', 'Shrimp', 10); 
INSERT INTO Contains VALUES ('04', 'Water', 20); 
INSERT INTO Contains VALUES ('05', 'Steak', 1); 
INSERT INTO Contains VALUES ('05', 'Rice', 20); 
INSERT INTO Contains VALUES ('06', 'Steak', 1); 
INSERT INTO Contains VALUES ('06', 'Spaguetti', 10); 

Le résultat attendu de la requête est:

Rice and ice tea 
Steak with rice 

Puisque ce sont les deux seules recettes avec quantité suffisante dans entrepôt.

EDIT: les pommes de terre avec du riz ne doit pas apparaître comme une recette mais pas dans la liste contient

Merci pour l'entrée et le temps. Toute aide est la bienvenue :)

+0

Veuillez poster le code que vous avez écrit jusqu'ici. Les gens n'aiment généralement pas écrire votre code pour vous. –

+0

Aussi dans quelle base de données est-ce que la façon de le faire peut différer légèrement en fonction de l'environnement. – Payload

+0

@ Mitch j'étais BASCULEMENT avec toute clause, mais se perdre dans les clauses imbriquées:/ @Payload Il est un ami qui m'a demandé de le faire et il est juste pour elle de garder une trace des recettes qu'elle peut faire avec le contenu de sa cuisine. Elle a une salle de stockage abusive lol – Martin

Répondre

2

J'utilise >= ALL opérateur:

SELECT name 
    FROM Recipe R 
WHERE 0 >= ALL (SELECT C.quantity - F.quantity 
        FROM Food F 
      INNER JOIN Contains C 
        USING (designation) 
        WHERE C.nrecipe = R.nrecipe); 

L'orthographe correcte est la recette, et vous avez utilisé des noms différents pour certaines colonnes (recepie, nrecipe, nrecepie) donc je l'ai changé. Notez qu'au lieu d'utiliser une clé primaire varchar, vous devez utiliser une clé numérique.

Edit:

SELECT name 
    FROM Recipe R 
WHERE 0 >= ALL (SELECT C.quantity - F.quantity 
        FROM Food F 
      INNER JOIN Contains C 
        USING (designation) 
        WHERE C.nrecipe = R.nrecipe) 
    AND EXISTS(SELECT NULL 
       FROM Contains C 
       WHERE C.nrecipe = R.nrecipe); 
+0

+1 aujourd'hui, j'ai appris sur l'opérateur ALL. – geofftnz

+0

Merci mon pote, je n'ai pas copié le coller il fallait que je le transpose tout et ai juste tapé donc il y a quelques bugs. Cela semble bien fonctionner mais il y a un problème de plus. Cela m'a donné un résultat qui n'était pas présent et j'ai oublié de le signaler. Il ne devrait pas donner un nom de recette s'il n'y a aucun élément de nourriture. Comme un test, je vais ajouter à la première page, mettre INSERT INTO Recettes VALEURS ('07', 'Pommes de terre avec du riz'); et il apparaîtra en conséquence et je n'ai pas voulu cela. – Martin

+0

@Martin: J'ai édité. Je ne pourrais pas trouver une manière plus élégante de faire ceci, pour être honnête. –

0

Ceci est dans SQL Server, car c'est ce que j'ai:

select 
    r.name 
from 
    Recepie r 
where 
    not exists 
    (
     select 1 
     from 
      [Contains] c 
     where 
      c.nrecipe = r.nrecepie and 
      not exists 
      (
       select 1 
       from 
        Food f 
       where 
        f.designation = c.designation and 
        f.quantity >= c.quantity 
      ) 
    ) 

Ce qui en langage clair et simple est « Donne-moi toutes les recettes où il n'y a pas d'ingrédients de quantité insuffisante "

+0

Cela fonctionne aussi bien que l'autre réponse donnée mais a le même problème que j'ai oublié de signaler. S'il existe une recette mais qu'elle n'est pas présente dans la table Contient, elle ne doit pas être affichée – Martin