1 Rappels importants
2 Les expressions entre attributs
3 Les fonctions d'agrégat d'enregistrements en SQL
Annexe 1 Solutions des exercices ou exemples
>>> Retour page précédente
Toute requête renvoie une table comportant un ou plusieurs attribut et zéro ou plusieurs enregistrements.
Dans le cas où la requête renvoie un seul attribut et un seul enregistrement,
le contenu une valeur qui peut être utilisée telle que dans une expression d'une autre requête.
La requête suivante ... | ||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
select * from facture
where facNoFou=(
select fourNo from Fourniseur where fourNom="toto"
) ;
| ||||||||||||||||||||||||||||||
... est divisible en plusieurs sous-parties. | ||||||||||||||||||||||||||||||
a) select * from facture where facNoFou=(QUELQUE CHOSE);
et
b) select fourNo from Fourniseur where fourNom="toto" ;
| ||||||||||||||||||||||||||||||
La partie b) donne une table résultat ... | ||||||||||||||||||||||||||||||
select fourNo from Fourniseur
where fourNom="toto" ;
| ||||||||||||||||||||||||||||||
... qui est substituée (remplace et utilisée) dans la partie a) ... | ||||||||||||||||||||||||||||||
select * from facture where facNoFou=("F023");
| ||||||||||||||||||||||||||||||
| ||||||||||||||||||||||||||||||
... pour donner le résultat ci-dessous : | ||||||||||||||||||||||||||||||
|
Dans le cas où une requête renvoie une seule colonne, le contenu peut être utilisé comme une liste pour l'opérateur IN comme suit :
| soit la table liste : |
|
<fourNo> | <fourNom> | suite des champs |
---|---|---|
F001 | premier fournisseur | ... |
F023 | toto | ... |
Par ailleurs, il existe des clauses ensemblistes qui permettent d'assembler, soustraire ou faire l'intersection de deux requêtes :
INTERSECT : intersection, ne sont affichées que les lignes présentes dans les deux requêtes.
MINUS : différence, le résultat sont les lignes de la première requête dont on a supprimé celles qui sont aussi dans la seonde.
Note : les résultats de chaque requête doivent avoir la même forme (mêmes type et nombre d'attributs).
Note 2 : les clauses Intersect et minus ne sont pas utilisables dans ms-Access (yek, yek, yek!), il faut faire autrement (cf exo sur les opérateurs ensemblistes). Retour index
Lors de requêtes, il peut être nécessaire d'effectuer des calculs sur les attributs.
Calcul de prix TTC.
Soit un catalogue, donnez requête SQL qui affiche la liste des tarifs HT, le montant de la TVA et le prix TTC des articles.
a) taux fixe : TVA=19,6%
Article(codeA, descA, prixHT)
b) Le taux de TVA dépend du type de taux de l'article.
Article(codeA, descA, prixHT, typeTVA)
TauxTaxe(codeT, tauxTaxe)
Dans certains cas, nous désirons faire apparaître des totaux ou autres calculs sur des valeurs.
Pour cela, on utilise des fonctions (dites d'agrégat car elles regroupent - agrègent- plusieurs lignes).
Ces fonctions sont à utiliser conjointement à la clause GROUP BY
Certaines fonctions ne sont utilisables que sur des attributs numériques
(sinon on obtient des résultats inattendus ou une erreur).
3.1 Le comptage : count(*)
Il sert à compter le nombre d'enregistrements.Rédigez la requête permettant de compter le nombre d'articles ;
Le MR est composé de la relation :
3.2 Les fonctions courantes : avg(a), sum(a)
Elles servent à calculer, respectivement, la moyenne et la somme d'un attribut d'une tableCalculer la somme des factures du fournisseur 10 ainsi que le montant moyen des factures ;
Le MR est composé de la relation :
3.3 Les fonctions spécialisées : max(a), min(a)
Renvoient le(s) enregistrement(s) ayant pour valeur de l'attribut a la valeur maximum/minimum de l'ensemble des enregistrements.Le MR est composé de la relation :
- Donnez les numéros des dernières factures reçues.
- Donnez les numéros et montants de la première et de la dernière facture du fournisseur 10
3.4 La clause having
Cette clause est très utile lorsqu'on veut effectuer une sélection des lignes dans la table résultat de la requête.Rédigez la requête qui affiche l'article "AZ345" sans utiliser la clause Where.
Donnez la liste des catégories de TVA qui comportent plus de 10 articles.
On effectue la requête de comptage et on ajoute une clause Having pour éliminer les lignes qui ne correspondent pas à la demande.
Donnez la liste des clients qui ont passé au moins une commande de plus se 5000€
Clé étrangère : cliNo référence cliNo dans Client
Clé étrangère : cdeNo référence cdeNo dans Commande
Clé étrangère : artCode référence artCode dans Article
Chapitre 2
Calcul du prix TTC : prixTTC=prixHT + TVA = prixHT + prixHT*TauxTVA/100 = prixHT( 1+tauxTVA/100)a) taux fixe : TVA=19,6%
b) Le taux de TVA dépend du type de taux de l'article.
from Article, TauxTaxe
Where typeTVA=codeT ;
Chapitre 3.1
Rédigez la requête permettant de compter le nombre d'articles ;Chapitre 3.2
Calculer la somme des factures du fournisseur 10 ainsi que le montant moyen des factures ;Chapitre 3.3
Donnez les numéros des dernières factures reçues.Donnez les numéros et montants de la première et de la dernière facture du fournisseur 10
From Facture
Where facNo in (
union
Select min(facNo) from Facture where facNoFou=10 // la plus petite
Chapitre 3.4
Rédigez la requête qui affiche l'article "AZ345" sans utiliser la clause Where.having artCode="AZ345" ;
where artCode="AZ345" ;
Donnez la liste des catégories de TVA qui comportent plus de 10 articles.
On effectue la requête de comptage et on ajoute une clause Having pour éliminer les lignes qui ne correspondent pas à la demande.
where Categorie.catNum=Article.catNum
group by Categorie.catNum, catDesc
having count(*) > 10 ;
Donnez la liste des clients qui ont passé au moins une commande de plus se 5000€
from LigneCdeArticle
group by cdeNum
;
from LigneCdeArticle
group by cdeNum
having cdeMontant > 5000
;
from LigneCdeArticle
group by cdeNum
having sum(cdePVenteHT*cdeQté) > 5000
;
Note : les éléments ou lignes qui sont issues de la requête ci-dessus sont surlignées dans la suite de l'explication.
b) Recherche des clients
1ère méthode
Attention : on obtient les n° et noms du client, mais aussi le n° de cde.
De plus, il peut y avoir des clients qui auraient passé plusieurs commandes >5000€ et on les verrai affichés plusieurs fois.
from LigneCdeArticle, Commande, Client
where Client.cliNo=Commande.cliNo
and Commande.cdeNum=LigneCdeArticle.cdeNum
group by Client.cliNo, cliNom, cdeNum
having sum(cdePVenteHT*cdeQté) > 5000
;
Cette méthode est plus propre car nous n'affichons plus le n° de commande (et un client sélectionné n'est affiché qu'une seule fois).
La requête initiale produit une table de n° de commandes.
On va rechercher les clients qui ont passé ces commandes :
a) la requête initiale est ajoutée dans la clause from
from Client, Commande, (
from LigneCdeArticle
group by cdeNum
having sum(cdePVenteHT*cdeQté) > 5000
where Client.cliNo=Commande.cliNo
and Commande.cdeNum=cdeNum_rechechee
;
from Client, Commande
where Client.cliNo=Commande.cliNo
and Commande.cdeNum in (
from LigneCdeArticle
group by cdeNum
having sum(cdePVenteHT*cdeQté) > 5000
;