--- title: BDR - grTP1 - Grp_2 tags: grTP1 --- [//]: <> (Ne pas modifier ce qui est au dessus SVP.) # TP3 ### Exercice 1 1. Quels sont les noms des recettes de plus de 90 calories par personne ? ```SQL SELECT nom_recette FROM recette WHERE (calories_recette/nb_personnes) > 90; ``` 2. Quels sont les descriptifs des produits présents dans le réfrigérateur ? ```sql SELECT descriptif_produit FROM produit JOIN rangement USING (num_rangement) WHERE lower(nom_rangement) = 'réfrigérateur'; ``` 3. Quels sont les noms des recettes composées de fruits de mer ? ```sql SELECT nom_recette FROM recette JOIN composition USING (num_recette) JOIN ingredient USING (num_ingredient) JOIN type_ingredient USING (num_type_ingredient) WHERE lower(nom_type_ingredient) = 'fruit de mer'; ``` 4. Quels sont les noms des recettes n’utilisant pas de fruits de mer ? ```sql SELECT nom_recette FROM recette EXCEPT SELECT nom_recette FROM recette JOIN composition USING (num_recette) JOIN ingredient USING (num_ingredient) JOIN type_ingredient USING (num_type_ingredient) WHERE lower(nom_type_ingredient) = 'fruit de mer'; ``` 5. Les questions suivantes ne font intervenir qu’une partie des ingrédients : ceux de type « matière grasse ». Nous allons donc créer une vue pour simplifier ces requêtes. i. Écrivez une requête SELECT retournant les ingrédients du type « matière grasse » (seules les colonnes de la table ingredient seront retournées) ```sql SELECT * FROM ingredient JOIN type_ingredient USING (num_type_ingredient) WHERE lower(nom_type_ingredient) = 'matière grasse'; ``` ii. À partir de cette requête, créez une vue ingredient_gras ```sql CREATE VIEW ingredient_gras AS ( SELECT num_ingredient, nom_ingredient, num_type_ingredient FROM ingredient JOIN type_ingredient USING (num_type_ingredient) WHERE lower(nom_type_ingredient) = 'matière grasse' ); ``` iii. Affichez le contenu de la vue ```sql SELECT * FROM ingredient_gras; ``` iv. Quelles sont les recettes ayant plus de deux ingrédients gras différents ? ```sql SELECT nom_recette FROM recette JOIN composition USING (num_recette) LEFT JOIN ingredient_gras USING (num_ingredient) GROUP BY nom_recette HAVING count(nom_ingredient) >= 2; ``` v. Quels sont les rangements ayant des ingrédients gras ? ```sql SELECT nom_rangement FROM produit JOIN rangement USING (num_rangement) LEFT JOIN ingredient_gras USING (num_ingredient) GROUP BY nom_rangement HAVING count(nom_ingredient) > 0; ``` vi. Pour tous les ingrédients gras, donnez en quelles quantités ils sont présents chez la famille (à partir de la table produit). Nous voulons afficher tous les ingrédients, même ceux qui ne sont pas disponible chez la famille. ```sql SELECT MIN(num_ingredient) AS num_ingredient, nom_ingredient, SUM(quantite_produit) AS quantite_produit_gras FROM ingredient_gras LEFT JOIN produit USING (num_ingredient) GROUP BY nom_ingredient; ``` vii. Si votre requête précédente renvoie des quantités NULL, modifiez la en remplaçant ces valeurs NULL par des 0. ```sql SELECT MIN(num_ingredient) AS num_ingredient, nom_ingredient, COALESCE(SUM(quantite_produit),0) AS quantite_produit_gras FROM ingredient_gras LEFT JOIN produit USING (num_ingredient) GROUP BY nom_ingredient; ``` 6. En utilisant la méthodologie des questions 5.i à 5.iii, créez une vue donnant la quantité de matière grasse dans chaque recette. ```sql= SELECT num_recette, COALESCE(SUM( CASE WHEN nom_type_ingredient = 'matière grasse' THEN quantite_composition ELSE 0 END ), 0) AS quantite_gras FROM recette JOIN composition USING(num_recette) JOIN ingredient USING(num_ingredient) JOIN type_ingredient USING(num_type_ingredient) GROUP BY num_recette; ``` ``` sql= CREATE VIEW quantite_gras AS ( SELECT num_recette, COALESCE(SUM( CASE WHEN nom_type_ingredient = 'matière grasse' THEN quantite_composition ELSE 0 END ), 0) AS quantite_gras FROM recette JOIN composition USING(num_recette) JOIN ingredient USING(num_ingredient) JOIN type_ingredient USING(num_type_ingredient) GROUP BY num_recette ); ``` ``` sql= SELECT * FROM quantite_gras ORDER BY num_recette; ``` 7. Pour chaque recette, si la quantité de matière grasse est ◦ > à 120 : affichez « recette trop grasse » ◦ < à 50 mais > à 0 : affichez « recette légère » ◦ = à 0 : affichez « recette non grasse » ◦ sinon : affichez « recette moyennement grasse » ```sql= SELECT num_recette, nom_recette, CASE WHEN quantite_gras > 120 THEN 'recette trop grasse' WHEN quantite_gras < 50 AND quantite_gras > 0 THEN 'recette légère' WHEN quantite_gras = 0 THEN 'recette non grasse' ELSE 'recette moyennement grasse' END AS contenu_gras FROM quantite_gras JOIN recette USING (num_recette); ``` 8. Quels sont les noms des recettes qui utilisent du jaune d’œuf ou de la viande rouge ou les deux à la fois? ```sql= SELECT nom_recette FROM recette JOIN composition USING (num_recette) JOIN ingredient USING (num_ingredient) JOIN type_ingredient USING (num_type_ingredient) WHERE lower(nom_ingredient) IN ('jaune d''oeuf','oeuf entier') OR lower(nom_type_ingredient) = 'viande rouge'; ``` 9. Quels sont les types d’ingrédient des produits qui seront périmés entre début novembre 2015 et fin décembre 2015 ? ```sql= SELECT DISTINCT nom_type_ingredient FROM type_ingredient JOIN ingredient USING(num_type_ingredient) JOIN produit USING(num_ingredient) WHERE date_peremption BETWEEN '01/11/2015' AND '31/12/2015'; ``` 10. Quels sont les noms des rangements qui contiennent au moins un ingrédient de type légume et au moins un ingrédient de type fruit ? ```sql= SELECT DISTINCT nom_rangement FROM rangement JOIN produit USING(num_rangement) JOIN ingredient USING(num_ingredient) JOIN type_ingredient USING(num_type_ingredient) WHERE nom_type_ingredient = 'fruit' INTERSECT SELECT DISTINCT nom_rangement FROM rangement JOIN produit USING(num_rangement) JOIN ingredient USING(num_ingredient) JOIN type_ingredient USING(num_type_ingredient) WHERE nom_type_ingredient = 'légume'; ``` 11. Quels sont les noms des rangements dans lesquels nous trouvons des ingrédients nécessaires à la recette des crêpes ? ```sql= SELECT DISTINCT nom_rangement FROM rangement JOIN produit USING(num_rangement) JOIN ingredient USING(num_ingredient) JOIN composition USING(num_ingredient) JOIN recette USING(num_recette) WHERE nom_recette = 'crêpes'; ``` 12. Combien y a-t-il de recettes dans la base de données ? ```sql= SELECT count(*) AS Nombre_Recettes FROM recette; ``` 13. Combien de recettes utilisent de l’œuf ? ```sql= SELECT COUNT(DISTINCT num_recette) AS Nombre_Recettes FROM recette JOIN composition USING (num_recette) JOIN ingredient USING (num_ingredient) WHERE nom_ingredient LIKE '%oeuf%'; ``` 14. Triez les type d’ingrédients par ordre croissant du nombre d’ingrédients associés et affichez le nom du type, le nombre d’ingrédients, et la quantité totale dans les rangements. ```sql= SELECT num_type_ingredient, COUNT(DISTINCT num_ingredient) AS nb_ingredients, COALESCE(SUM(quantite_produit),0) AS quantite_produits FROM type_ingredient JOIN ingredient USING (num_type_ingredient) LEFT JOIN produit USING (num_ingredient) LEFT JOIN rangement USING (num_rangement) GROUP BY num_type_ingredient ORDER BY nb_ingredients; ``` 15. Donnez pour chaque recette le nombre d’ingrédients différents qu’elle contient et la quantité moyenne de ces ingrédients (les unités n’étant pas cohérentes entre les ingrédients, cette quantité ne sera pas réaliste). Vous pourrez arrondir à deux chiffres après la virgule. ```sql= SELECT nom_recette, COUNT(DISTINCT num_ingredient) AS nb_ingredients, ROUND(AVG(quantite_composition), 2) AS quantite_moyenne FROM recette JOIN composition USING(num_recette) JOIN ingredient USING(num_ingredient) GROUP BY nom_recette; ``` 16. Donnez pour chaque recette le nombre d’ingrédients nécessaires et le nombre de rangements où on trouve au moins un de ces ingrédients. ```sql= SELECT nom_recette, COUNT(DISTINCT num_ingredient) AS nb_ingredients, COUNT(DISTINCT num_rangement) AS nb_rangements FROM recette JOIN composition USING(num_recette) JOIN ingredient USING(num_ingredient) JOIN produit USING(num_ingredient) JOIN rangement USING(num_rangement) GROUP BY nom_recette; ``` 17. Donnez la(es) nom(s) de la(es) recette(s) la(les) plus riche(s) (celle(s) qui contien(nen)t le plus de calories par personne). ```sql= SELECT nom_recette FROM recette WHERE calories_recette/nb_personnes = ( SELECT MAX(calories_recette/nb_personnes) FROM recette ); ``` 18. Donnez les noms des recettes ayant un ingrédient commun avec la recette des crêpes. ```sql= SELECT DISTINCT nom_recette FROM recette JOIN composition USING(num_recette) WHERE num_ingredient IN ( SELECT num_ingredient FROM recette JOIN composition USING(num_recette) WHERE nom_recette = 'crêpes' ); ``` 19. Créez une vue appelée liste_courses contenant tous les ingrédients dont il ne reste qu’un seul ou aucun produit. La vue devra contenir le nom des ingrédients et le nom du type de l’ingrédient. ```sql= CREATE VIEW liste_courses AS ( SELECT DISTINCT nom_ingredient, nom_type_ingredient FROM type_ingredient RIGHT JOIN ingredient USING(num_type_ingredient) FULL JOIN produit USING(num_ingredient) WHERE COALESCE(quantite_produit, 0) <= 1 ); ``` 20. Affichez le contenu de la vue précédente en triant par ordre alphabétique du nom des types d’ingrédient et pour un même type d’ingrédient par ordre alphabétique des ingrédients. ```sql= SELECT nom_ingredient, nom_type_ingredient FROM liste_courses ORDER BY nom_type_ingredient, nom_ingredient; ``` 21. Créez une vue qui contient les ingrédients pour lesquels nous avons des produits. Pour chaque ingrédient nous voulons son prix de revient pour 100 grammes en se basant sur le prix du produit le moins cher. La vue contiendra trois attributs : la référence de l’ingrédient, le nom de l’ingrédient et son coût unitaire. Affichez la. ```sql= CREATE VIEW ingredient_prix AS( SELECT num_ingredient, nom_ingredient, MIN(prix_produit)/MIN(quantite_produit) AS prix FROM ingredient JOIN produit USING(num_ingredient) GROUP BY num_ingredient, nom_ingredient ); ``` 22. Créez une vue contenant les numéros des recettes pour lesquelles nous avons tous les ingrédients (il existe au moins un produit pour chaque ingrédient). Affichez la. ```sql= CREATE VIEW recettes_possibles AS ( SELECT num_recette FROM recette EXCEPT SELECT num_recette FROM recette JOIN composition USING(num_recette) JOIN ingredient USING(num_ingredient) WHERE num_ingredient IN ( SELECT DISTINCT num_ingredient FROM type_ingredient RIGHT JOIN ingredient USING(num_type_ingredient) FULL JOIN produit USING(num_ingredient) WHERE COALESCE(quantite_produit, 0) = 0 ) ); ``` 23. Utilisez les vues précédentes pour calculer le coût des recettes réalisables (celles dont l’utilisateur possède tous les ingrédients). Affichez le nom des recettes et leur coût. ```sql= SELECT nom_recette, ROUND(SUM(quantite_composition*prix), 2) AS cout_recette FROM recettes_possibles JOIN recette USING(num_recette) JOIN composition USING(num_recette) JOIN ingredient_prix USING(num_ingredient) GROUP BY nom_recette ORDER BY cout_recette; ```