---
# System prepended metadata

title: BDR - grTP1 - Grp_2
tags: [grTP1]

---

---
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;
```

