|
Publicité ' | ||||||||||||||||||||||||
|
|
#1 | ||||
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Bonjour à tous !
Pour résumer ma situation, je sélectionne des produits et leurs informations propres dans une table produits "T_Prod" ainsi que des éléments se trouvant dans d'autres tables, reliées par des clés étrangères. Voici, dans un premier temps, ma requête : Code :
Mes produits peuvent en faite chacun avoir des déclinaisons : "ce produit est disponible en bleu et en rouge" et chacune de ces variantes est susceptible d'avoir un prix bien distinct : "la version bleu de ce produit coûte 5€, la rouge coûte 6€". Ces prix sont indiqués dans une colonne "Prix_Variante" de la table "T_Variante" à laquelle j'ai affecté un alias "V" lors de la requête (d'où le "V.Prix_Variante"). Pour repérer quelles variantes sont affectées à quel produit (je pars du principe qu'une variante ne peut être affectée qu'à un seul produit et qu'un produit peut avoir plusieurs variantes : relation 1-N), je me base sur la colonne "Id_Prod" de la table "T_Variante", dont la valeur doit correspondre à l'une des entrées de la colonne "Id_Prod" de la table "T_Prod" (voir le schéma relationnel). La requête fonctionne mais, forcément, si mon produit écope de plusieurs variantes, alors j'aurai autant de lignes qu'il y a des variantes dans mes résultats de requête. Ces lignes seront en tout point identiques, à l'exception du prix de la variante. Mon souhait est le suivant : Que je ne récupère qu'une seule entrée pour un produit, avec dans la colonne "Prix_Variante" la valeur la plus petite parmi l'ensemble des prix de variantes recensés. J'ai déjà repéré la fonction "MIN" et l'instruction "GROUP BY" qui pourraient répondre à mes attentes. J'ai essayé de cette façon, mais sans succès : Code :
|
||||
|
|
00
|
|
|
#2 |
![]() ![]() Alain Ingénieur d'études décisionnel Inscription : mai 2002 Messages : 4 445 ![]() |
Toutes les colonnes de la clause SELECT qui ne sont pas l'objet d'une fonction de regroupement doivent être reprises dans la clause GROUP BY.
Tu trouveras ici un tutoriel sur les regroupements
__________________
Modérateur Langage SQL N'oubliez pas le bouton et pensez aux balises [code]Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur ![]() |
|
|
10
|
|
|
#3 |
|
Membre Expert
![]() Pacman PacmanBusiness analyst Inscription : juin 2004 Messages : 1 417 ![]() |
Salut !
La contraposée de ce que dit al1, et qui semble être ce que tu cherches : Les colonnes qui ne sont pas dans le GROUP BY, il faut les enlever de ton SELECT En fait, il te suffit de te poser une simple question : si tu veux une ligne par groupe, et que tu demandes à ton SELECT des colonnes qui sont liées au détail, comment peut-on savoir quelle valeur retourner pour le groupe ? (En fait dans certains SGBD, ça te retourne carrément une erreur de syntaxe)
__________________
(c'est ma photo) Paku, Paku ! Pour les jeunes incultes : non, je ne suis pas un pokémon... Le pacblog : http://pacmann.over-blog.com/ |
|
10
|
|
|
#4 | |
![]() ![]() Alain Ingénieur d'études décisionnel Inscription : mai 2002 Messages : 4 445 ![]() |
Citation:
Pour les autres, ça retourne des valeurs prises pas complètement au hasard mais selon des règles qui n'ont rien à voir avec l'algèbre relationnelle.
__________________
Modérateur Langage SQL N'oubliez pas le bouton et pensez aux balises [code]Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur ![]() |
|
|
|
00
|
|
|
#5 |
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Bonjour à vous deux, et d’emblée merci beaucoup pour ces réponses si rapides !
J'avoue avoir un peu de mal en SQL, je suis novice et je m'attaque, je trouve, à des requêtes plutôt maouss-costaud aux vues de mes compétences ! Je pense avoir saisi ce que tu veux dire pacmann. De façon encore plus concrète : "Si je veux une seule variante de mon produit, comment expliciter quelles valeurs du produit renvoyer pour la variante en question" ? Je pensai que la question ne se posait pas étant donné que ces valeurs sont "communes" aux deux variantes. Donc d'un point de vue de la requête, je ne peux pas sélectionner des colonnes qui n'ont rien à voir avec mon regroupement ? Impossible donc de récupérer les infos de ma table "T_Prod" ? Il me faudrait faire deux requêtes distinctes ? J'excuse par avance mon ignorance et ma lenteur de compréhension... Edit : Effectivement j'avais une erreur avec la requête formulée dans mon premier post. Je travaille sur Visual Web Developer 2010 Express avec une BDD SQL. |
|
|
00
|
|
|
#6 |
|
Invité de passage
![]() Consultant en Business Intelligence Inscription : mai 2011 Messages : 5 ![]() |
Bonjour,
Il suffit de rajouter tout ce qui est dans ta clause SELECT dans la clause GROUP BY. |
|
|
00
|
|
|
#7 | ||
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Merci à toi aussi ghosn pour ta réponse.
J'ai essayé une requête simple de la manière suivante : Code :
|
||
|
|
00
|
|
|
#8 |
|
Membre émérite
![]() Olivier DehorterIngenieur de recherche - Ecologue Inscription : juin 2003 Messages : 697 ![]() |
bonjour
Regardes la clause SELECT, la colonne que tu demandes n'y est pas, donc la requete ne l'affiche pas |
|
|
00
|
|
|
#9 |
![]() ![]() Alain Ingénieur d'études décisionnel Inscription : mai 2002 Messages : 4 445 ![]() |
Une requête n'affiche que les colonnes présentes dans la clause SELECT.
__________________
Modérateur Langage SQL N'oubliez pas le bouton et pensez aux balises [code]Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur ![]() |
|
|
00
|
|
|
#10 | ||
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Ça y est c'est bon... Merci beaucoup pour votre aide, la requête fonctionne impeccablement.
D'un point de vue pratique, c'est ok, je sais désormais comment faire (merci beaucoup à tous ! Voici la requête fonctionnelle si jamais ça peut aider... Code :
|
||
|
|
00
|
|
|
#11 | ||
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Encore un petit dérangement, désolé.
Je pousse le vice encore plus loin... Dans la table des variantes "T_Variante", j'ai ajouté deux champs supplémentaires "PourcentPromo_Variante" et "PrixOkaz_Variante". Je souhaite en effet que chaque variante d'un même produit puisse bénéficier d'un pourcentage de promo ou d'un prix fixe d'occasion indépendant. Comment faire pour que, lors de ma requête, je sélectionne les valeurs de ces deux colonnes qui sont associées au prix minimal de toutes les variantes confondues d'un même produit ? Plus concrètement, admettons Code :
J'espère avoir été suffisamment clair dans ma question... Merci d'avance ! |
||
|
|
00
|
|
|
#12 | |||||
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Citation:
Si tu veux le min(Prix_Variante) par id_prod, puis que tu souhaites afficher d'autres colonnes il est probablement nécessaire de passer par une jointure avec une sous-requête calculant le min : Code :
Code :
|
|||||
|
|
20
|
|
|
#13 |
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Waw...
Impressionnant... Je ne pouvais pas espérer une réponse plus précise ! J'avoue ne jamais avoir effectué de sous-requête. C'est incroyable les requêtes complexes que ça permet d'effectuer de manière plutôt intuitive en fin de compte ! Juste une petite précision par rapport à ce code... dans la première requête, "mini" est en faite un alias donné à la sous-requête, ce qui revient à faire ensuite une jointure sur une table "virtuelle" contenant les résultats de la sous-requête. Est-ce bien cela ? En tout cas, un grand merci ! Je m'empresse de tester cette requête.
|
|
|
00
|
|
|
#14 |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
|
|
|
00
|
|
|
#15 | ||
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Je reviens à l'assaut avec une ultime question pour que la requête soit parfaite :
Lorsque j'ai des prix identiques sur deux variantes, la fonction MIN sur la colonne du prix me renvoie les deux... ce qui me pose problème lorsque je vais traiter mes données. Peut-on ne garder que la variante ayant la plus grande valeur dans la colonne "PourcentPromo_Variante" ou "PrixOkaz_Variante" (si l'une est pleine, l'autre est de toute façon "NULL" ; par contre il se peut que les deux soient "NULL") ? Quelque chose du genre... : Code :
|
||
|
|
00
|
|
|
#16 | ||
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Oui tu peux prendre le MAX et le fait qu'il n'y ait que des NULLS n'est pas un problème, par contre le GROUP BY doit s'écrire (et bien sûr faire partie de la sous-requête
Code :
A lire sur le GROUP BY et MySql http://cedric-duprez.developpez.com/...fier-group-by/ |
||
|
|
00
|
|
|
#17 |
|
Invité de passage
![]() Inscription : mai 2011 Messages : 11 ![]() |
Encore merci pour ta réponse !
![]() Personnellement je travaille sur SQLServer donc ça devrait être interprété correctement si j'ai bien compris. |
|
|
00
|
|
|
#18 | ||||
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
Alors autant en profiter... et utiliser un APPLY qui me semble très adapté pour ce cas, et sera je pense plus performant pour peu qu'il dispose d'un index adéquat :
Code SQL :
sur le principe, quelque chose comme : Code SQL :
|
||||
|
|
00
|
|
|
#19 |
|
Membre Expert
![]() Inscription : août 2008 Messages : 1 271 ![]() |
Merci aieeeuuuuu, je ne connais pas APPLY, mais j'avoue avoir fait toutes mes réponses en étant persuadé que Malikiwi était sur MySql...
Avec Oracle j'aurais peut être envisagé keep dense_rank first pour éviter les 2 niveaux de sous-requêtes, pour ma culture personelle est ce que ça fonctionne sur SqlServer ? |
|
|
00
|
|
|
#20 |
|
Membre Expert
![]() ![]() Inscription : janvier 2010 Messages : 1 084 ![]() |
pas a ma connaissance, mais les fonctions de fenêtrage sous SQL Server ne sont disponibles que depuis la version 2005, tout comme l'opérateur APPLY. Et pour celui-ci, même si le plus gros intérêt et de pouvoir appliquer des fonctions tables prenant en paramètre une/des valeur(s) de la table externe, il permet également des gains de perfs dans certains cas, comme le cas présent.
|
|
|
00
|
Copyright © 2000-2012 - www.developpez.com