jointure
@@ -101,12 +101,13 @@ WHERE gauche IS NULL;
|
||||
```
|
||||

|
||||
|
||||
Lister les articles dont la famille n'existe pas.
|
||||
**Exercice :** Lister les articles dont la famille n'existe pas.
|
||||
|
||||
```sql
|
||||
select * from article
|
||||
left join famille on famille.code = article.famille_code
|
||||
where famille.code is null
|
||||
>> MENMA Plant Menthe Pomme
|
||||
```
|
||||
|
||||
Attention ! La valeur `null` ne peut être comparée à rien. L'égalité avec null retourne ni vrai ni faux mais null. Ainsi null n'est pas égal à null. Pour la comparaison avec null il faut utiliser les mots-clés `is` ou `is not`.
|
||||
@@ -198,6 +199,7 @@ Avantages :
|
||||
- Robuste face aux valeurs NULL (pas d’ambiguïté).
|
||||
- Souvent optimisé par le moteur en anti-semi-join (c’est-à-dire que le moteur ne lit pas plus de lignes que nécessaire dans la table de droite). Les jointures qui passent par des produits cartésiens sont consommatrices en ressources.
|
||||
|
||||
**Exercice :** Lister les articles dont la famille n'existe pas.
|
||||
|
||||
```sql
|
||||
select * from article
|
||||
@@ -207,6 +209,8 @@ where not exists (
|
||||
)
|
||||
```
|
||||
|
||||
Ou avec l'opérateur `not in`
|
||||
|
||||
```sql
|
||||
select * from article
|
||||
where famille_code not in (
|
||||
@@ -215,7 +219,7 @@ where famille_code not in (
|
||||
)
|
||||
```
|
||||
|
||||
Cette requête est elle aussi équivalente cependant il existe un risque de mauvaise interprétation. Si le sous-select contient au moins un NULL, alors toutes les lignes sont rejetées (car la comparaison avec la valeur NULL dans id NOT IN ( …, NULL, … ) est indéterminée.)
|
||||
Cette requête est elle aussi équivalente cependant il existe un risque de mauvaise interprétation. Si le sous-select contient au moins un NULL, alors toutes les lignes sont rejetées (car la comparaison avec la valeur NULL dans code NOT IN ( …, NULL, … ) est indéterminée.)
|
||||
|
||||
Il existe plusieurs syntaxes permettant d’obtenir le même résultat. Toutefois, certains points méritent d’être pris en compte :
|
||||
- **Consommation de ressources** : un même résultat peut être produit par des requêtes dont le coût en temps d’exécution ou en mémoire diffère sensiblement.
|
||||
|
||||
@@ -15,9 +15,21 @@ select count(*) from adherent
|
||||
|
||||
On peut compter sur n'importe quelle colonne, dans ce cas, pour ne pas avoir à choisir on utilise le caractère joker *.
|
||||
|
||||
**Exercice :** Compter le nombre d'articles de la famille 02CHOU.
|
||||
|
||||
```sql
|
||||
select count(*) from article
|
||||
where famille_code = '02CHOU'
|
||||
>> 29
|
||||
```
|
||||
|
||||
### distinct
|
||||
|
||||
En ajoutant le mot clé `distinct` l'opération s'effectue sur les **valeurs uniques** d'une ou de plusieurs colonnes.
|
||||
En ajoutant le mot clé `distinct` l'opération s'effectue sur les **valeurs uniques** d'une ou de plusieurs colonnes.select codepostal,
|
||||
count(case when genre = 1 then 1 end) as nb_hommes,
|
||||
count(case when genre = 2 then 1 end) as nb_femmes
|
||||
from adherent
|
||||
group by codepostal;
|
||||
|
||||
**Exercice :** Afficher le nombre de codes postaux différents trouvés dans la table adhérent.
|
||||
|
||||
|
||||
@@ -18,13 +18,44 @@ Parce qu’elle doit produire une table (un jeu de résultats) indépendante **a
|
||||
- Dans le SELECT, une sous-requête peut être corrélée (elle utilise des colonnes de la requête principale) ou non.
|
||||
- Dans le WHERE, idem : elle peut être corrélée (EXISTS, IN dépendant de la ligne en cours) ou non (test fixe).
|
||||
|
||||
**Exercice : ** Sélectionner les articles dont le prix est supérieur à la moyenne générale des prix des articles.
|
||||
|
||||
Dans un langage procédural on utiliserait deux étapes pour obtenir le résultat. Première étape calculer la moyenne des prix
|
||||
|
||||
```sql
|
||||
select * from article a1 where prix > (
|
||||
select avg(prix) from article
|
||||
where famille_code = a1.famille_code
|
||||
)
|
||||
select avg(prix) from article
|
||||
>> 5.8060418562329390
|
||||
```
|
||||
|
||||
Puis dans un deuxième temps faire la requête de sélection avec la valeur trouvée.
|
||||
|
||||
```sql
|
||||
select * from article where prix > 5.8060418562329390
|
||||
```
|
||||
|
||||
Il est possible d'utiliser une sous requête à l'intérieur de la requête principale. La sous requête calcule la moyenne à l'endroit nécessaire.
|
||||
|
||||
```sql
|
||||
select * from article
|
||||
where prix > (select avg(prix) from article);
|
||||
```
|
||||
|
||||
**Exercice : ** Sélectionner les articles dont le prix est supérieur à la moyenne des prix des articles de la même famille.
|
||||
|
||||
Cette fois ci il faut calculer les moyennes des prix pour chacune des familles et comparer les articles avec la moyenne correspondante. Ce n'est plus possible en programmation procédurale.
|
||||
|
||||
La sous requête permet de calculer pour chaque ligne d'article la moyenne correspondante à la famille du dit article.
|
||||
|
||||
```sql
|
||||
select code, article, prix from article a1
|
||||
where prix > (
|
||||
select avg(prix) from article
|
||||
where famille_code = a1.famille_code
|
||||
)
|
||||
```
|
||||
|
||||
Remarquez l'utilisation de l'alias `a1` sur la table de la requête principale pour pouvoir être injecter sans confusion dans la sous requête car celle-ci utilise la même table.
|
||||
|
||||
## Sous-requête scalaire
|
||||
|
||||
> une sous-requête scalaire est une sous-requête qui retourne **une seule valeur** (un scalaire, c’est-à-dire une seule ligne et une seule colonne).
|
||||
|
||||
10
window.md
10
window.md
@@ -129,6 +129,16 @@ ORDER BY est obligatoire lorsque LEAD() est utilisé. La séquence des lignes do
|
||||
|
||||
column_2 est la colonne qui défini l'ordre des lignes lors de la récupération de la valeur suivante. Vous pouvez spécifier plus d'une colonne.
|
||||
|
||||
**Exercice :** Afficher le chiffre d'affaire mensuel pour chaque mois, puis dans une deuxième colonne le chiffre d'affaire du mois précédent
|
||||
|
||||
```sql
|
||||
select * ,
|
||||
lag(total) over (order by mois) as total_mois_p,
|
||||
total - lag(total) over (order by mois) as difference,
|
||||
lag(total, 12) over (order by mois) as total_annee_p
|
||||
from ca_mensuel
|
||||
order by mois
|
||||
```
|
||||
|
||||
#### première valeur
|
||||
|
||||
|
||||
Reference in New Issue
Block a user