cours sql. base de données exemple pour le cours (1/2) client (noclient, nom, prénom, ddn, rue,...
TRANSCRIPT
Cours SQLCours SQL
Base de données exemple pour Base de données exemple pour le cours (1/2)le cours (1/2)
ClientClient ( (noClientnoClient, nom, prénom, ddn, rue, CP, ville), nom, prénom, ddn, rue, CP, ville)ProduitProduit ( (noProdnoProduit, libellé, prixUnitaire, uit, libellé, prixUnitaire, noFournisseurnoFournisseur))FournisseurFournisseur (n (noFournisseuroFournisseur, raisonSociale), raisonSociale)CommandeCommande ( (noClient, noProduit, noClient, noProduit, dateCommandedateCommande, ,
quantité)quantité)
Clés primairesClés primairesClés étrangèresClés étrangères
Client
noClientnomprénomddnrueCPville
Produit
noProduitlibellépunoFournisseur
Commande
noClientnoProduitdateCommandequantité
Fournisseur
noFournisseurraisonSociale
Base de données exemple pour le cours (2/2)
Syntaxe générale de la commande SELECT
SELECT *|{[ALL|DISTINCT]
expression [nomColonne]
[,expression [nomColonne]]… }
FROM relation [alias] [,relation [alias] …]
[WHERE condition]
[GROUP BY nomColonne [,nomColonne]…]
[HAVING condition]
[ORDER BY nomColonne [ASC|DESC]
[,nomColonne [ASC|DESC]…]
SQL et la casse des caractères SQL et la casse des caractères (majuscule/minuscule)(majuscule/minuscule)
Il n’y a pas de différence entre des noms (ou Il n’y a pas de différence entre des noms (ou identifiants) écrits en majuscules ou en identifiants) écrits en majuscules ou en minusculesminuscules ex. noms d’attributs, de tables, de contraintes…ex. noms d’attributs, de tables, de contraintes…
Seul cas où la casse est prise en compte : la Seul cas où la casse est prise en compte : la comparaison de chaînes de caractèrescomparaison de chaînes de caractères
SELECT *FROM ClientWHERE nom = ’Dupont’
Select *From CLIENTwhere NOM = ’Dupont’
Trouver les Trouver les noClientnoClient et et dateCommandedateCommande de toutes les de toutes les CommandesCommandes
Projection d'une relation et la clause DISTINCT
SELECT noClient, dateCommandeFROM Commande
noClientnoClient dateCommandedateCommande
100100 04/05/200304/05/2003
200200 12/4/200312/4/2003
100100 5/1/20045/1/2004
300300 25/2/200425/2/2004
400400 30/1/200430/1/2004
400400 30/1/200430/1/2004
Commande SQLéquivalente
Trouver les Trouver les noClientnoClient et et dateCommandedateCommande de toutes les de toutes les CommandesCommandes
La clause DISTINCT
SELECT DISTINCT noClient, dateCommandeFROM Commande
R1=Commande[noClient, datecommande])
Expression algébrique équivalente
noClientnoClient dateCommandedateCommande
100100 04/05/200304/05/2003
200200 12/4/200312/4/2003
100100 5/1/20045/1/2004
300300 25/2/200425/2/2004
400400 30/1/200430/1/2004
Restriction d’une relation sur Restriction d’une relation sur une conditionune condition
Sélectionner les Articles dont le prix est inférieur à Sélectionner les Articles dont le prix est inférieur à 20€ et le numéro est supérieur à 3020€ et le numéro est supérieur à 30SELECT *
FROM Article
WHERE prixUnitaire < 20 AND noArticle > 30
noArticlenoArticle libellélibellé prixUnitaireprixUnitaire
3131 BrosseBrosse 1212
4040 TableauTableau 9.999.99
5050 VisseuseVisseuse 19.9919.99
R1=Article[prixUnitaire < 20 AND noArticle > 30 ]
Exp. algéb. équivalent
e
Restriction : syntaxe d'une Restriction : syntaxe d'une conditioncondition
SELECT * FROMSELECT * FROM nom-relation nom-relation
WHEREWHERE conditioncondition
Syntaxe de conditionSyntaxe de condition
- - conditionSimple | NOT (condition) | condition conditionSimple | NOT (condition) | condition {AND|OR} condition {AND|OR} condition
Syntaxe de conditionSimpleSyntaxe de conditionSimpleexpression {= | <|>|<=|>=|<>|!=} expression |expression {= | <|>|<=|>=|<>|!=} expression |
expression expression [NOT]BETWEEN[NOT]BETWEEN expression expression ANDAND expression| expression|
expression expression IS [NOT]IS [NOT] NULL NULL
expression [expression [NOTNOT] ] ININ listeConstantes| listeConstantes|
expression [expression [NOT]LIKENOT]LIKE patron patron
Restriction : ExemplesRestriction : Exemples
Produits dont le prix est compris entre 50 et 100Produits dont le prix est compris entre 50 et 100€€SELECTSELECT * * FROMFROM Produit ProduitWHEREWHERE prixUnitaire >= 50 prixUnitaire >= 50 ANDAND prixUnitaire <= 100 prixUnitaire <= 100
SELECTSELECT * * FROMFROM Produit ProduitWHEREWHERE prixUnitaire prixUnitaire BETWEENBETWEEN 50 50 ANDAND 100 100
Produits dont le prix est inférieur à 50Produits dont le prix est inférieur à 50€€ ou ou supérieur à 100 supérieur à 100 €€
SELECTSELECT * * FROMFROM ProduitProduitWHEREWHERE prixUnitaire < 50 prixUnitaire < 50 OROR prixUnitaire > 100 prixUnitaire > 100
Restriction : Opérateurs IS NULL Restriction : Opérateurs IS NULL et LIKEet LIKE
Commandes en quantité indéterminée (null)Commandes en quantité indéterminée (null)SELECTSELECT * * FROMFROM CommandeCommandeWHEREWHERE quantité quantité IS NULLIS NULL
Clients dont le nom commence par B, se termine par B Clients dont le nom commence par B, se termine par B et contient au moins 3 caractèreset contient au moins 3 caractères
SELECTSELECT **FROMFROM ClientClientWHEREWHERE nom nom LIKELIKE ‘B%B’ ‘B%B’
LIKELIKE recherche des chaînes de caractères correspondant à un recherche des chaînes de caractères correspondant à un patronpatron où : où :
%% : désigne une suite de : désigne une suite de zéro à nzéro à n caractères quelconques caractères quelconques_ _ : désigne : désigne un et un seulun et un seul caractère quelconque caractère quelconque
Restriction : Opérateur IN Restriction : Opérateur IN
Clients dont le nom est Dupont, Durant ou Clients dont le nom est Dupont, Durant ou MartinMartin
SELECTSELECT * * FROMFROM ClientClientWHEREWHERE nom nom ININ (‘Dupond’, ‘Durant’, ‘Martin’) (‘Dupond’, ‘Durant’, ‘Martin’)
Clients dont le nom n'est pas dans l'ensemble Clients dont le nom n'est pas dans l'ensemble {Dupont, Durant, Martin}{Dupont, Durant, Martin}
SELECTSELECT * * FROMFROM ClientClientWHEREWHERE nom nom NOT INNOT IN (‘Dupond’, ‘Durant’, (‘Dupond’, ‘Durant’,
‘Martin’)‘Martin’)
Restriction et projectionRestriction et projection Produire les noClient et dateCommande des Produire les noClient et dateCommande des
Commandes dont la date est postérieure au Commandes dont la date est postérieure au 01/01/200401/01/2004
SELECTSELECT noClient, dateCommande noClient, dateCommande
FROMFROM Commande Commande
WHEREWHERE dateCommande > ’01/01/2004’dateCommande > ’01/01/2004’
noClientnoClient dateCommandedateCommande
100100 5/1/20045/1/2004
300300 25/2/200425/2/2004
400400 30/1/200430/1/2004
Exp. Algébr. équivalente
{noClient, dateCommande} ( dateCommande>’01/01/2004’
( Commande))
Produit cartésienProduit cartésien
SELECTSELECT **
FROM FROM relation, relationrelation, relation
Ex. Produire toutes les combinaisons possibles de Client Ex. Produire toutes les combinaisons possibles de Client et de Commandeet de Commande
SELECT SELECT * *
FROMFROM Client, CommandeClient, Commande
Client X CommandeExp. Algébr. équivalente
Jointure Jointure
SELECTSELECT attribut1 [,attribut2, …]attribut1 [,attribut2, …]
FROMFROM relation1,relation2 relation1,relation2 [,relation3,…][,relation3,…]
WHEREWHERE conditioncondition
Cette commande SELECT combineCette commande SELECT combine produit produit cartésien, restriction et projectioncartésien, restriction et projection
Exp. Algébr. équivalente
{attribut1, attribut2…} ( condition ( (relation1 x relation2) x relation3)…)
N.B. Nécessité de préfixer le nom d’un attribut par sa relation en cas d’ambiguïté
Jointure : exemple de requêteJointure : exemple de requête
ex. ex. Liste des commandes avec le Liste des commandes avec le nom du clientnom du client
SELECTSELECT nom, Client.noClient, nom, Client.noClient, noProduit,dateCommande,quantiténoProduit,dateCommande,quantité
FROMFROM Commande, ClientCommande, Client
WHEREWHERE Client.noClient =Client.noClient =Commande.noClientCommande.noClient
Commande Client
nom,Client.noClient…
Arbre algébrique canonique correspondant à l’expression SQL
(SGBDR)
x
Client.noClient = Commande.noClient
rest
rict
ion
proj
ecti
on
Jointure : autre exemple de Jointure : autre exemple de requêterequêteex. ex. Produits commandés en quantité Produits commandés en quantité
supérieure à 100 et dont le prix supérieure à 100 et dont le prix dépasse 1000 dépasse 1000 €€. Afficher les numéros . Afficher les numéros de produit, leur libellé , leur prix de produit, leur libellé , leur prix unitaire ainsi que la date de la unitaire ainsi que la date de la commande.commande.
SELECTSELECT Produit.noProduit, Produit.noProduit, libellé, libellé, prixUnitaire, dateprixUnitaire, date
FROMFROM Produit, CommandeProduit, CommandeWHEREWHERE quantité > 100 quantité > 100 ANDAND prixUnitaire >1000 prixUnitaire >1000 ANDAND Produit.noProduit = Produit.noProduit =
Commande.noProduitCommande.noProduitArbre algébrique canonique
CommandeProduit
Produit.noProduit,libellé…
x
quantité > 100 AND prixUnitaire >1000
AND Produit.noProduit = Commande.noProduit
Jointure : utilisation d'aliasJointure : utilisation d'alias
Utilisation d’Utilisation d’aliasalias pour alléger l’écriture d'une requête incluant des pour alléger l’écriture d'une requête incluant des jointuresjointures
ex. ex. Liste des commandes avec le nom et le numéro du client Liste des commandes avec le nom et le numéro du client
SELECT SELECT C2C2.noClient, nom, date, quantité.noClient, nom, date, quantitéFROMFROM Commande Commande C1C1 , Client , Client C2C2WHEREWHERE C1C1.noClient = .noClient = C2C2.noClient.noClient
CommandeCommande alias alias C1C1 ClientClient alias alias C2C2
Opérations ensemblistes Opérations ensemblistes (UNION, INTERSECT, EXCEPT)(UNION, INTERSECT, EXCEPT) Trouver les noms et prénoms des employés qui sont aussi des passagersTrouver les noms et prénoms des employés qui sont aussi des passagers
noEmployénoEmployé nomEmpnomEmp prénomEmpprénomEmp
1010 HenryHenry JohnJohn
1515 ConradConrad JamesJames
3535 JenquaJenqua JessicaJessica
4646 LeconteLeconte JeanJean
noPassagernoPassager nomPassnomPass prénomPassprénomPass
44 HarryHarry PeterPeter
7878 ConradConrad JamesJames
99 LandLand RobertRobert
466466 LeconteLeconte JeanJean
Employé Passager
(SELECT nomEmp as nom, prénomEmp as prénom FROM Employé)
INTERSECT(SELECT nomPass as nom, prénomPass as prénom FROM Passager)
nomnom prénomprénom
ConradConrad JamesJames
LeconteLeconte JeanJean
Expression de calcul sur les colonnesExpression de calcul sur les colonnesdans la liste de projectiondans la liste de projection
Liste des noArticle avec le prixUnitaire avant et après Liste des noArticle avec le prixUnitaire avant et après inclusion d’une taxe de 15%.inclusion d’une taxe de 15%.
SELECT noArticle, prixUnitaire, prixUnitaire*1.15 as prixTTC
FROM Article
noArticleprixUnitaire prixTTC10 10.99 12.6420 12.99 14.9440 25.99 29.8950 22.99 26.4460 15.99 18.3970 10.99 12.6480 26.99 31.0481 25.99 29.8990 25.99 29.8995 15.99 18.39
Expression de calcul sur les colonnesExpression de calcul sur les colonnesdans la condition (du WHERE)dans la condition (du WHERE)
Une condition peut comporter une expression de calculUne condition peut comporter une expression de calcul
ex:Liste des noArticle dont le prix toutes taxes comprises (TTC) dépasse ex:Liste des noArticle dont le prix toutes taxes comprises (TTC) dépasse 20€20€
SELECT noArticleFROM ArticleWHERE prixUnitaire*1.15 > 40
noArticlenoArticle
4040
5050
8080
8181
9090
SELECT *FROM CommandeWHERE dateCommande = CURRENT_DATE
Une expression peut aussi faire appel à des fonctions
ex: Liste des commandes de la journée
Fonctions d’agrégation Fonctions d’agrégation Une fonction d'agrégation opère sur un groupe de valeurs d’attributs et Une fonction d'agrégation opère sur un groupe de valeurs d’attributs et produit une valeur résultat uniqueproduit une valeur résultat unique (extension de l’algèbre (extension de l’algèbre relationnelle)relationnelle)
SELECTSELECT fctAgrégation fctAgrégation FROMFROM relation(s) [WHERE condition]relation(s) [WHERE condition]
fctAgrégation fctAgrégation opère sur les lignes de la relation résultat :opère sur les lignes de la relation résultat :
COUNTCOUNT(*)(*) : retourne le nombre de lignes de la relation résultat : retourne le nombre de lignes de la relation résultat COUNTCOUNT([distinct]expr)([distinct]expr) : nombre de valeurs non NULL : nombre de valeurs non NULL
(distinctes) de (distinctes) de exprexpr MAXMAX(n(n)) : valeur maximum de : valeur maximum de nn MINMIN(n(n)) : valeur minimum de : valeur minimum de nn SUMSUM(n(n)) : somme des valeurs de : somme des valeurs de n n (ignore les valeurs NULL)(ignore les valeurs NULL) AVGAVG(n(n)) : valeur moyenne de : valeur moyenne de nn (ignore les valeurs NULL) (ignore les valeurs NULL)
Où Où nn est une expression numérique et est une expression numérique et exprexpr une expression quelconque une expression quelconque
Fonctions d’agrégationFonctions d’agrégation
Nombre total d’articles et prix unitaire moyen
SELECT COUNT(*) AS nbArticles, AVG (prixUnitaire) AS prixMoyen
FROM Article
nbArticlesnbArticles prixMoyenprixMoyen
1515 9.509.50
Nombre de prixUnitaires non null différents
SELECT COUNT(distinct prixUnitaire) AS nbPrixFROM Article
nbPrixnbPrix
88
Fonctions d’agrégationFonctions d’agrégation : : Contraintes d’utilisationContraintes d’utilisation
Une fonction d’agrégation doit être utilisée dans une clause Une fonction d’agrégation doit être utilisée dans une clause SELECT SELECT sanssans résultats individuels résultats individuels
SELECT noProduit, max(prixUnitaire) SELECT noProduit, max(prixUnitaire) FROMFROM Produit Produit
Requête Requête invalideinvalide puisque plusieurs noProduit et un seul maximum. puisque plusieurs noProduit et un seul maximum.
Une fonction d’agrégation peut être utilisée dans une sous-Une fonction d’agrégation peut être utilisée dans une sous-requête requête
sélection de résultats individuels dans la requête englobantesélection de résultats individuels dans la requête englobante
SELECT noProduit, libelléSELECT noProduit, libelléFROM ProduitFROM ProduitWHERE prixUnitaire = WHERE prixUnitaire =
(SELECT(SELECT max (prixUnitaire)max (prixUnitaire) FROM FROM Produit)Produit)
Faux !!
Partition de relations (GROUP BY)Partition de relations (GROUP BY)ex. ex. Nombre de produits commandés par clientNombre de produits commandés par client
SELECT SELECT noClient, COUNT(*) noClient, COUNT(*)
FROM FROM CommandeCommandeGROUP BYGROUP BY noClient noClient
1) Les commandes sont groupées par numéro de client1) Les commandes sont groupées par numéro de client2) pour chaque groupe, afficher le numéro du client concerné 2) pour chaque groupe, afficher le numéro du client concerné
par le groupe et le nombre de commandes.par le groupe et le nombre de commandes.
N.B.N.B. : chaque expression du SELECT doit avoir une valeur : chaque expression du SELECT doit avoir une valeur uniqueunique par par groupegroupe..
Partition de relations (GROUP Partition de relations (GROUP BY)BY)
ex. ex. Nombre de produits commandés par clientNombre de produits commandés par clientSELECT SELECT noClient, COUNT(*) noClient, COUNT(*)
FROM FROM CommandeCommandeGROUP BYGROUP BY noClient noClient
noProduitnoProduit dateCommadateCommandende
noCliennoClientt
44 5/1/20035/1/2003 1010
55 5/1/20035/1/2003 1010
2020 14/5/200314/5/2003 1212
2828 15/8/200315/8/2003 1212
6868 15/8/200315/8/2003 1212
5959 20/9/200320/9/2003 1515
noClienoClientnt
totalProduitotalProduitsts
1010 22
1212 33
1515 11
ex. ex. Quantité totale de produits commandés par client en dehors du Quantité totale de produits commandés par client en dehors du produit F565produit F565
SELECT SELECT noClient, SUM(quantité)noClient, SUM(quantité)FROM FROM CommandeCommandeWHERE WHERE noProduit <> ‘F565’noProduit <> ‘F565’GROUP BY GROUP BY noClientnoClient
1) Les tuples de Commande ne vérifiant pas la condition sont exclus1) Les tuples de Commande ne vérifiant pas la condition sont exclus2) Les commandes restantes sont groupées par numéro de client2) Les commandes restantes sont groupées par numéro de client3) pour chaque groupe, afficher le numéro du client concerné par le 3) pour chaque groupe, afficher le numéro du client concerné par le
groupe et la somme des quantités.groupe et la somme des quantités.
Une clause Une clause HAVINGHAVING permet de restreindre les groupes permet de restreindre les groupes
Partition de relations (GROUP Partition de relations (GROUP BY)BY)
Partition de relations (GROUP BY)Partition de relations (GROUP BY)ex. ex. Quantité moyenne commandée par produit pour les produits Quantité moyenne commandée par produit pour les produits
ayant fait l’objet de plus de 3 commandes. Ignorer les ayant fait l’objet de plus de 3 commandes. Ignorer les commandes concernant le client C47.commandes concernant le client C47.
SELECTSELECT noProduit, AVG(quantité)noProduit, AVG(quantité)FROMFROM CommandeCommandeWHEREWHERE noClient != ‘C47’noClient != ‘C47’GROUP BYGROUP BY noProduitnoProduitHAVINGHAVING COUNT(*) > 3COUNT(*) > 3
1) Les tuples de Commande ne vérifiant pas la condition WHERE sont 1) Les tuples de Commande ne vérifiant pas la condition WHERE sont exclusexclus
2) Les commandes restantes sont groupées par numéro de produit2) Les commandes restantes sont groupées par numéro de produit3) pour chaque groupe, compter le nombre d’éléments et éliminer les 3) pour chaque groupe, compter le nombre d’éléments et éliminer les
groupes à moins de 3 éléments.groupes à moins de 3 éléments.4) pour les groupes restants, afficher le numéro de produit et la quantité 4) pour les groupes restants, afficher le numéro de produit et la quantité
moyenne.moyenne.
N.B. : La clause HAVING ne s’utilise qu’avec un GROUP BY.N.B. : La clause HAVING ne s’utilise qu’avec un GROUP BY.
Partition de relations (GROUP BY)Partition de relations (GROUP BY)
ex. ex. Nombre de produits commandés par client et par dateNombre de produits commandés par client et par date SELECTSELECT noClient, dateCommmande, noClient, dateCommmande, COUNT(noProduit) AS nbProduitsCOUNT(noProduit) AS nbProduitsFROMFROM CommandeCommandeGROUPGROUP BY BY noClient, dateCommandenoClient, dateCommande
noProdunoProduitit
dateCommadateCommandende
noClientnoClient
44 5/1/20035/1/2003 1010
55 5/1/20035/1/2003 1010
2020 14/5/200314/5/2003 1212
2828 15/8/200315/8/2003 1212
6868 15/8/200315/8/2003 1212
5959 20/9/200320/9/2003 1515
noClienoClientnt
dateCommadateCommandende
nbProduitnbProduitss
1010 5/1/20035/1/2003 22
1212 14/5/200314/5/2003 11
1212 15/8/200315/8/2003 22
1515 20/9/200320/9/2003 11
Il est possible de partitionner sur plusieurs colonnes (attributs)
Tri du résultat d’une requête Tri du résultat d’une requête (ORDER BY)(ORDER BY)
Possibilité de trier les résultats d’une requête par rapport à Possibilité de trier les résultats d’une requête par rapport à une ou plusieurs de ses colonnesune ou plusieurs de ses colonnes SELECT colonne(s)SELECT colonne(s) FROM relation(s) [WHERE condition]FROM relation(s) [WHERE condition] ORDER BY ORDER BY colonnecolonne [ASC|DESC],[ASC|DESC], [,colonne ASC|DESC]..][,colonne ASC|DESC]..]
Où Où ASCASC : ordre ascendant (par défaut) : ordre ascendant (par défaut)DESCDESC : ordre descendant : ordre descendant
ex. liste des commandes par ordre croissant du numéro de client et ex. liste des commandes par ordre croissant du numéro de client et par ordre chronologique inverse de la datepar ordre chronologique inverse de la date
SELECTSELECT **FROM FROM Commande Commande ORDER BYORDER BY noClient, dateCommande descnoClient, dateCommande desc
Requêtes imbriquéesRequêtes imbriquées
Le résultat d’une requête peut être utilisé dans Le résultat d’une requête peut être utilisé dans une condition de la clause WHERE d’une une condition de la clause WHERE d’une commande SELECTcommande SELECT
- sous-requête /requête imbriquée- sous-requête /requête imbriquée
SELECTSELECT colonne(s)colonne(s)FROMFROM relation(s)relation(s)WHEREWHERE expression expression [NOT]IN[NOT]IN (sous-requête) | (sous-requête) | {{EXISTSEXISTS | | NOT EXISTSNOT EXISTS} (sous-requête)} (sous-requête)
Requêtes imbriquées : opérateur Requêtes imbriquées : opérateur IN / NOT IN (test d’appartenance IN / NOT IN (test d’appartenance
à un ensemble)à un ensemble)Nom des clients ayant passé commande le Nom des clients ayant passé commande le
24/10/200024/10/2000
SELECTSELECT nomnom
FROMFROM ClientClient
WHERE WHERE noClient noClient ININ (SELECT noClient(SELECT noClient
FROMFROM CommandeCommande
WHEREWHERE dateCommande=’24/10/2000’)dateCommande=’24/10/2000’)
Requêtes imbriquées : opérateur Requêtes imbriquées : opérateur EXISTS / NOT EXISTS (test EXISTS / NOT EXISTS (test
d’ensemble vide)d’ensemble vide)Clients ayant passé au moins une commandeClients ayant passé au moins une commande
SELECTSELECT **FROMFROM Client C1Client C1WHEREWHERE EXISTSEXISTS (SELECT * (SELECT *
FROMFROM Commande C2 Commande C2WHEREWHERE C1.noClient=C2.noClient) C1.noClient=C2.noClient)
Clients n’ayant passé aucune commandeClients n’ayant passé aucune commande
SELECTSELECT **FROMFROM Client C1Client C1WHERE WHERE NOT EXISTSNOT EXISTS (SELECT *(SELECT *
FROMFROM Commande C2Commande C2WHEREWHERE C1.noClient=C2.noClient) C1.noClient=C2.noClient)
Quelques règles de nommage …Quelques règles de nommage …Nom d’une colonne dans la relation résultat :Nom d’une colonne dans la relation résultat :
- - par défaut, nom de l’attribut ou de l’expression dont par défaut, nom de l’attribut ou de l’expression dont elle est issue :elle est issue :
SELECT * FROMSELECT * FROM ProduitProduit
SELECT AVG(prixUnitaire)FROM ProduitSELECT AVG(prixUnitaire)FROM Produit
- - renommage possible :renommage possible :
SELECT noProduit SELECT noProduit ASAS ""Numéro produitNuméro produit"" FROMFROM ProduitProduit
noProduinoProduitt
libellélibellé prixUnitairprixUnitairee
AVG(prixUnitaire)AVG(prixUnitaire)
Numéro produitNuméro produit