112
Chapitre 5 • Le langage SQL DML
ce qui nous donnerait :
Ce résultat, en apparence correct, est pourtant erroné (indépendamment du fait que
les clients sans commandes ne sont pas repris). En effet, le résultat de la jointure
représente des commandes et non des clients. En particulier, le compte du client
C400 est compté trois fois, pour un total de 1050 au lieu de 350. Le calcul de la
somme des comptes se fait donc sur des ensembles de commandes et non de clients.
Tout client qui possède plus d’une commande verra son compte intervenir plus
d’une fois dans la somme. En revanche, le comptage des commandes par localité est
correct. Il faudra, pour répondre à la question posée, procéder en deux étapes indépendantes.
Dans certains cas cependant, il est possible de citer des fonctions agrégatives à
plusieurs niveaux, pour autant que toutes les fonctions sommatives (sum et avg)
s’adressent au niveau le plus bas des jointures, les fonctions count, max et min
pouvant s’appliquer à tous les niveaux. La requête ci-dessous illustre cette structure.
Elle recherche, pour chaque client, le nombre de commandes et le montant total de
ces commandes. La première information est relative au niveau COMMANDE tandis
que la seconde dérive du niveau DETAIL. Pour obtenir le nombre exact de
commandes, on utilisera le modifieur distinct dans la fonction count.
select M.NCLI,count(distinct M.NCOM),sum(QCOM*PRIX)
from
COMMANDE M, DETAIL D, PRODUIT P
where M.NCOM = D.NCOM
and
D.NPRO = P.NPRO
group by M.NCLI
5.5.6 Peut-on éviter l’utilisation de données groupées ?
Il est possible d’éviter la clause group by lorsque le concept latent dans une table
est explicitement représenté par une autre table, et que le regroupement ne sert qu’à
la sélection. On recherche par exemple les produits dont on a commandé plus de 500
unités en 2005. La forme qui semble s’imposer est la suivante, qui extrait les
produits comme concept latent de la table DETAIL, via la colonne NPRO :
select D.NPRO
from
DETAIL D, COMMANDE M
where D.NCOM = M.NCOM
and
DATECOM like '%2005'
group by D.NPRO
having sum(QCOM) > 500
LOCALITE
sum(COMPTE)
count(*)
Lille
Namur
Poitiers
Toulouse
720
-4580.00
1050.00
-8700.00
1
1
3
2
Chapitre 5 • Le langage SQL DML
ce qui nous donnerait :
Ce résultat, en apparence correct, est pourtant erroné (indépendamment du fait que
les clients sans commandes ne sont pas repris). En effet, le résultat de la jointure
représente des commandes et non des clients. En particulier, le compte du client
C400 est compté trois fois, pour un total de 1050 au lieu de 350. Le calcul de la
somme des comptes se fait donc sur des ensembles de commandes et non de clients.
Tout client qui possède plus d’une commande verra son compte intervenir plus
d’une fois dans la somme. En revanche, le comptage des commandes par localité est
correct. Il faudra, pour répondre à la question posée, procéder en deux étapes indépendantes.
Dans certains cas cependant, il est possible de citer des fonctions agrégatives à
plusieurs niveaux, pour autant que toutes les fonctions sommatives (sum et avg)
s’adressent au niveau le plus bas des jointures, les fonctions count, max et min
pouvant s’appliquer à tous les niveaux. La requête ci-dessous illustre cette structure.
Elle recherche, pour chaque client, le nombre de commandes et le montant total de
ces commandes. La première information est relative au niveau COMMANDE tandis
que la seconde dérive du niveau DETAIL. Pour obtenir le nombre exact de
commandes, on utilisera le modifieur distinct dans la fonction count.
select M.NCLI,count(distinct M.NCOM),sum(QCOM*PRIX)
from
COMMANDE M, DETAIL D, PRODUIT P
where M.NCOM = D.NCOM
and
D.NPRO = P.NPRO
group by M.NCLI
5.5.6 Peut-on éviter l’utilisation de données groupées ?
Il est possible d’éviter la clause group by lorsque le concept latent dans une table
est explicitement représenté par une autre table, et que le regroupement ne sert qu’à
la sélection. On recherche par exemple les produits dont on a commandé plus de 500
unités en 2005. La forme qui semble s’imposer est la suivante, qui extrait les
produits comme concept latent de la table DETAIL, via la colonne NPRO :
select D.NPRO
from
DETAIL D, COMMANDE M
where D.NCOM = M.NCOM
and
DATECOM like '%2005'
group by D.NPRO
having sum(QCOM) > 500
LOCALITE
sum(COMPTE)
count(*)
Lille
Namur
Poitiers
Toulouse
720
-4580.00
1050.00
-8700.00
1
1
3
2
