Précédent   Forum des professionnels en informatique > Bases de données > Oracle
Oracle Forum Oracle : le serveur, les outils, ... Voir F.A.Q Oracle Tutoriels Oracle
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 19/02/2007, 15h21   #1
Candidat au titre de Membre du Club
 
Inscription : août 2003
Messages : 45
Détails du profil
Informations forums :
Inscription : août 2003
Messages : 45
Points : 11
Points : 11
Par défaut group by - order by

Bonjour,

Est-ce que la clause group by effectue un tri sur les champs spécifiés.
En gros, est ce qu'il est inutile de préciser la clause order by dans une requête de ce type :

Code :
1
2
3
4
5
 
SELECT gencod, actif, count(*)
FROM article
GROUP BY gencod, actif
ORDER BY gencod, actif
Je ne pose pas la question parce que j'ai la flemme d'écrire une requête supplémentaire mais parce que je veux utiliser cette requête dans une requête imbriquée et j'ai cru comprendre que la clause order by ne fonctionne pas dans ce cas (mais j'arrive à m'en sortir avec un group by donc tout va bien si ce dernier effectue le tri qui va bien...)

Merci d'avance pour vos lumières.
romstarr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 15h24   #2
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
ça marche... mais dans une requête imbriquée, j'ai du mal à voir en quoi l'ordre pourrait avoir de l'importance
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 15h30   #3
Expert Confirmé
 
Inscription : février 2006
Messages : 3 433
Détails du profil
Informations forums :
Inscription : février 2006
Messages : 3 433
Points : 3 462
Points : 3 462
Le document SQL Reference de la 10GR2 dit explicitement pour GROUP BY:

Citation:
The GROUP BY clause groups rows but does not guarantee the order of the result set. To order the groupings, use the ORDER BY clause.
et ORDER BY:

Citation:
Use the ORDER BY clause to order rows returned by the statement. Without an order_by_clause, no guarantee exists that the same query executed more than once will retrieve rows in the same order.
Pour être sûr que le résultat d'une requête est triée, il faut absolument utiliser ORDER BY.
__________________
P. Forstmann

AskTom Forums OTN doc 8, 9, 10 et 11
pifor est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 15h31   #4
Expert Confirmé
 
Homme
Chef de projet en SSII
Inscription : janvier 2004
Messages : 2 866
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Chef de projet en SSII
Secteur : Conseil

Informations forums :
Inscription : janvier 2004
Messages : 2 866
Points : 3 448
Points : 3 448
A partir de la 9i tu es obligé de préciser la clause order by si tu veux avoir des lignes triées.

Dans les versions précédentes d'oracle (au moins la 7 et la 8i), le group by triait les lignes.
__________________
Un problème sans solution est un problème mal posé

Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.
plaineR est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 15h39   #5
Candidat au titre de Membre du Club
 
Inscription : août 2003
Messages : 45
Détails du profil
Informations forums :
Inscription : août 2003
Messages : 45
Points : 11
Points : 11
Ok Merci.

Pour la requête imbriquée :

J'ai une table article (clé CIART) et une table Article-fournisseur (clé CIART, AFNUM avec un champ qui va préciser si c'est un fournisseur principal)
Voilà la requête que j'aurai écrite sous MS SQL server pour obtenir pour tous mes articles le premier fournisseur principal (ou pas si il n'y en a pas)

Code :
1
2
3
4
5
6
7
8
9
 
SELECT a.*, af.fournisseur
FROM article a, art_fou af
WHERE af.ciart=a.ciart
         AND af.afnum IN (SELECT top 1 afnum 
                               FROM art_fou 
                               WHERE ciart=a.ciart
                               ORDER BY AFFOUPRINC -- -1 si fournisseur principal, 0 sinon
                               )
romstarr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 15h49   #6
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
comme tu fais un IN toutes les lignes sont traitées alors l'ordre est inutile

Edit : je comprends... sous Oracle c'est complétement faux
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 15h54   #7
Candidat au titre de Membre du Club
 
Inscription : août 2003
Messages : 45
Détails du profil
Informations forums :
Inscription : août 2003
Messages : 45
Points : 11
Points : 11
Non j'ai le top 1 qui me retourne uniquement la première ligne en fonction de mon order by (et vu que j'ai un seul enregistrement de retourné je pourrai mettre = au lieu de in).

Sous Oracle (si le order by marchait ds les requêtes imbriquées), j'écrirais cette requête ainsi :

Code :
1
2
3
4
5
6
7
8
9
10
11
 
SELECT a.*, af.fournisseur
FROM article a, art_fou af
WHERE af.ciart=a.ciart
         AND af.afnum IN (SELECT afnum 
                                 FROM (SELECT afnum 
                                         FROM art_fou 
                                         WHERE ciart=a.ciart
                                         ORDER BY AFFOUPRINC -- -1 si fournisseur principal, 0 sinon
                                        )
                                 WHERE rownum=1)
romstarr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 16h06   #8
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
ou alors :

Code :
1
2
3
4
SELECT a.*, af.fournisseur
FROM article a, art_fou af
WHERE af.ciart=a.ciart
 AND AFFOUPRINC=-1
non ?

ou alors :

Code :
1
2
3
4
5
6
SELECT a.*, af.fournisseur
FROM article a, (
        SELECT ciart,afnum,MIN(AFFOUPRINC) AFFOUPRINC 
           FROM art_fou 
        GROUP BY ciart,afnum) af
WHERE af.ciart=a.ciart
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 16h55   #9
Candidat au titre de Membre du Club
 
Inscription : août 2003
Messages : 45
Détails du profil
Informations forums :
Inscription : août 2003
Messages : 45
Points : 11
Points : 11
La première requête va me retourner plusieurs lignes pour un seul article si j'ai plusieurs fournisseurs principaux et pas de ligne si j'ai pas de fournisseur principal --> j'en veux quoi qu'il arrive une seule (à part si j'ai pas de fournisseur du tout).

La deuxième requête avec le group by sur la clé primaire (?) ne va pas solutionner mon problème non plus.

Peut-être une autre idée?
romstarr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 17h01   #10
Rédacteur/Modérateur
 
Avatar de orafrance
 
Inscription : janvier 2004
Messages : 15 861
Détails du profil
Informations personnelles :
Âge : 35

Informations forums :
Inscription : janvier 2004
Messages : 15 861
Points : 16 212
Points : 16 212
je veux bien un petit test case parce qu'à mon avis, ta requête ne marche pas non plus du coup
orafrance est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 17h16   #11
Candidat au titre de Membre du Club
 
Inscription : août 2003
Messages : 45
Détails du profil
Informations forums :
Inscription : août 2003
Messages : 45
Points : 11
Points : 11
J'explique ma requête :

Code :
1
2
3
4
5
 
SELECT afnum 
FROM art_fou 
WHERE ciart=a.ciart
ORDER BY AFFOUPRINC -- -1 si fournisseur principal, 0 sinon
Cette requête imbriquée va me retourner la liste de tous mes fournisseurs pour un article sans distinction de fournisseur principal ou pas.
Par contre mon order by me permet d'avoir dans les premières lignes mes fournisseurs principaux (s'il y a).

Du coup la requête suivante me permet de me retourner mon premier identifiant de mon fournisseur souhaité :

Code :
1
2
3
4
5
6
7
8
 
SELECT afnum 
FROM (SELECT afnum 
          FROM art_fou 
          WHERE ciart=a.ciart
          ORDER BY AFFOUPRINC -- -1 si fournisseur principal, 0 sinon
         )
WHERE rownum=1
Non?

Bref il faut que j'arrive à touner cette requête bien comme il faut
romstarr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 17h19   #12
McM
Expert Confirmé Sénior
 
Inscription : juillet 2003
Messages : 3 450
Détails du profil
Informations forums :
Inscription : juillet 2003
Messages : 3 450
Points : 4 209
Points : 4 209
Y'a les fonctions analytiques, sinon, faut faire une fonction qui te ramènes pour un article donné, le premier fournisseur, mais niveau perfs, pas terrible.

Voici un test avec les fonctions analytiques, j'ai tenté de retransposer ça pour toi, mais faut tester.
Code :
1
2
3
4
5
6
7
8
SELECT *
FROM (
	SELECT a.*, af.ciart, af.afnum, af.fournisseur,
			row_number() over(PARTITION BY af.ciart ORDER BY af.affouprinc) RNUM
	FROM ARTICLE a, ART_FOU af
	WHERE af.ciart=a.ciart
	)
WHERE rnum = 1
__________________
More Code : More Bugs. Less Code : Less Bugs
McM est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 17h32   #13
Candidat au titre de Membre du Club
 
Inscription : août 2003
Messages : 45
Détails du profil
Informations forums :
Inscription : août 2003
Messages : 45
Points : 11
Points : 11
Je ne connais pas les fonctions analytiques mais la requête semble fonctionner.
Je vais essayer de comprendre la syntaxe maintenant.
Par contre effectivement niveau perf, c'est pas terrible car mes 2 tables sont assez conséquentes.
Merci du conseil en tous cas, j'vais tenter de gratter encore un peu pour voir si je ne trouve pas la requête qui tue.
romstarr est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 19/02/2007, 17h40   #14
Expert Confirmé
 
Homme
Chef de projet en SSII
Inscription : janvier 2004
Messages : 2 866
Détails du profil
Informations personnelles :
Sexe : Homme
Localisation : France, Loire Atlantique (Pays de la Loire)

Informations professionnelles :
Activité : Chef de projet en SSII
Secteur : Conseil

Informations forums :
Inscription : janvier 2004
Messages : 2 866
Points : 3 448
Points : 3 448
Pour plus d'infos sur les fonctions analytiques :
http://lalystar.developpez.com/fonctionsAnalytiques/
__________________
Un problème sans solution est un problème mal posé

Merci de poser vos questions sur le forum, je ne réponds pas aux questions posées par MP.
plaineR est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 21/02/2007, 15h02   #15
Candidat au titre de Membre du Club
 
Inscription : août 2003
Messages : 45
Détails du profil
Informations forums :
Inscription : août 2003
Messages : 45
Points : 11
Points : 11
Finalement j'ai opté pour la fonction. Je ne vais pas être tatillon sur la perf car la requête est tout de même très rapide.

Merci de votre aide.
romstarr est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité Cette discussion est résolue.
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 04h25.


 
 
 
 
Partenaires

Hébergement Web