[Résolu] [Requete] Besoin d'aide pour une requete

Eléphanteau du PHP | 11 Messages

10 oct. 2007, 12:34

Bonjour,

Je voudrais récupérer des données et je pense que c'est faisable en une seule requete. Le problème c'est que je ne sais pas comment.

J'ai la table suivante :

Code : Tout sélectionner

------------------------------------------------- | Pays | Division | Equipe | Joueur | Salaire | ------------------------------------------------- | France | L1 | Equipe1 | toto | 100 | | France | L1 | Equipe1 | titi | 200 | | France | L1 | Equipe1 | tata | 300 | | France | L2 | Equipe1 | toto | 100 | | France | L2 | Equipe1 | titi | 200 | | France | L2 | Equipe1 | tata | 300 | | France | L3 | Equipe1 | toto | 500 | | France | L3 | Equipe1 | titi | 500 | | France | L3 | Equipe1 | tata | 500 | | Belgiq | D1 | Equipe1 | toto | 100 | | Belgiq | D1 | Equipe1 | titi | 200 | | Belgiq | D1 | Equipe1 | tata | 300 | -------------------------------------------------
Je voudrais récupérer toutes les divisions (et les pays) où les joueurs de l'équipe 1 ont la même répartion de salaire (toto 100,titi 200 et tata 300)

cad obtenir ça :

Code : Tout sélectionner

------------------------------------------------- | Pays | Division | Equipe | Joueur | Salaire | ------------------------------------------------- | France | L1 | Equipe1 | toto | 100 | | France | L1 | Equipe1 | titi | 200 | | France | L1 | Equipe1 | tata | 300 | | France | L2 | Equipe1 | toto | 100 | | France | L2 | Equipe1 | titi | 200 | | France | L2 | Equipe1 | tata | 300 | | Belgiq | D1 | Equipe1 | toto | 100 | | Belgiq | D1 | Equipe1 | titi | 200 | | Belgiq | D1 | Equipe1 | tata | 300 | -------------------------------------------------
Est-ce réalisable en une requête ?


merci de votre aide

PoichOU
Modifié en dernier par PoichOU le 12 oct. 2007, 17:09, modifié 1 fois.

Eléphant du PHP | 73 Messages

10 oct. 2007, 12:39

Code : Tout sélectionner

SELECT Pays, Division, Equipe, Joueur, Salaire FROM Table WHERE Equipe = "Equipe1" AND Salaire BETWEEN 100 AND 300
ici on ramènera les infos pour les salaires compris entre 100 et 300

ou

Code : Tout sélectionner

SELECT Pays, Division, Equipe, Joueur, Salaire FROM Table WHERE Equipe = "Equipe1" AND Salaire IN (100,200,300)
ici on ramène que les infos pour salaire égal à 100, 200 ou 300
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

ViPHP
ViPHP | 2144 Messages

10 oct. 2007, 12:50

Je me permets une remarque : ta structure de donnée contient beaucoup de redondance de donnée, je pense que tu aurais intérêt à la revoir si tu le peux, avant d'aller plus loin dans le dévellopement.

Eléphanteau du PHP | 11 Messages

10 oct. 2007, 13:46

merci de ta réponse Sedril mais je ne connais pas la valeur des salaires.

Je vais essayer d'être plus clair, je voudrais connaitre les couples (pays,divisions,equipe) qui ont la même répartition des salaires entre les joueurs que celles du couple (France,L1,Equipe1).


iclo : oui oui tu as raison mais en fait la base existe déjà et les données aussi, je voudrais juste récupérer certaines données en une requete.

Eléphant du PHP | 73 Messages

10 oct. 2007, 13:54

Hmm... je viens de comprendre avec ton 2ème message qui est plus précis.

Code : Tout sélectionner

SELECT Pays, Division, Equipe, Joueur, Salaire FROM Table WHERE Salaire IN ( SELECT Salaire FROM Table WHERE Pays = "FRANCE" AND Division = "L1" AND Equipe = "Equipe1" ) ORDER BY Pays, Division, Equipe
Modifié en dernier par Sedril le 10 oct. 2007, 15:46, modifié 1 fois.
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

Eléphanteau du PHP | 11 Messages

10 oct. 2007, 14:03

ouai nikel c'est ça :D merkiiiiiiii

si je pousse le truc un peu plus loin je pourrais récupérer une réponse comme ça :

Code : Tout sélectionner

----------------------------------------------- | Pays | Division | Equipe | REP_IDENTIQUE | ----------------------------------------------- | France | L1 | Equipe1 | VRAI | | France | L2 | Equipe1 | VRAI | | France | L3 | Equipe1 | FAUX | | Belgiq | D1 | Equipe1 | VRAI | -----------------------------------------------
PS : il sert à quelque chose le ORDER BY Pays, Division, Equipe ?

Eléphant du PHP | 73 Messages

10 oct. 2007, 14:07

L'ORDER BY sert à faire un tri... pour obtenir la réponse dans l'ordre que tu as proposé.

Par contre j'ai un doute, supposons que dans l'équipe 1 il y ait un joueur de plus qui n'est pas dans les autres équipes ca donnerait quoi pour toi ?
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

Eléphanteau du PHP | 11 Messages

10 oct. 2007, 15:29

ok pour le order by.

L'exemple que tu dis n'est pas possible. Pour une même equipe il y a les memes joueurs (même nombre et même nom de joueur), seul le salaire diffère.



Edit :

Avec cette requete :

Code : Tout sélectionner

SELECT DISTINCT Pays, Division, Equipe, 'VRAI' as REP_IDENTIQUE FROM Table WHERE Salaire IN ( SELECT Salaire FROM Table WHERE Pays = "FRANCE" AND Division = "L1" AND Equipe = "Equipe1" ORDER BY Pays, Division, Equipe )
j'obtient :

Code : Tout sélectionner

----------------------------------------------- | Pays | Division | Equipe | REP_IDENTIQUE | ----------------------------------------------- | France | L1 | Equipe1 | VRAI | | France | L2 | Equipe1 | VRAI | | Belgiq | D1 | Equipe1 | VRAI | -----------------------------------------------
Et avec cette requete :

Code : Tout sélectionner

SELECT DISTINCT Pays, Division, Equipe, 'FAUX' as REP_IDENTIQUE FROM Table WHERE Salaire NOT IN ( SELECT Salaire FROM Table WHERE Pays = "FRANCE" AND Division = "L1" AND Equipe = "Equipe1" ORDER BY Pays, Division, Equipe )
j'obtient :

Code : Tout sélectionner

----------------------------------------------- | Pays | Division | Equipe | REP_IDENTIQUE | ----------------------------------------------- | France | L3 | Equipe1 | FAUX | -----------------------------------------------
t'as une idée comment je peux faire pour combiner les 2 select en un pour obtenir :

Code : Tout sélectionner

----------------------------------------------- | Pays | Division | Equipe | REP_IDENTIQUE | ----------------------------------------------- | France | L1 | Equipe1 | VRAI | | France | L2 | Equipe1 | VRAI | | France | L3 | Equipe1 | FAUX | | Belgiq | D1 | Equipe1 | VRAI | -----------------------------------------------
PoichOU

Eléphant du PHP | 73 Messages

10 oct. 2007, 15:45

Tu mets un UNION entre les 2 requêtes...

Tu peux supprimer les ORDER BY au passage, la clause ORDER BY n'apparait qu'à la fin d'une requête.
Image Un bon maître a ce souci constant : enseigner à se passer de lui.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

10 oct. 2007, 22:35

@PoichOU: je pense que tu devrais expliquer plus précisément ce que tu veux faire, parce que les mots que je lis ne correspondent pas aux requêtes que je vois. D'après ce que j'ai lu, tu veux récupérer la liste des équipes possédant exactement les même salaires qu'une équipe donnée (1x100 + 1x200 + 1x300). La requête que tu utilises renvoit la liste des équipes possédant au moins un joueur dont le salaire est égal à l'un des joueurs de l'équipe de référence (par exemple, 3x100, ou 1x200 + 2x300).

Eléphanteau du PHP | 11 Messages

11 oct. 2007, 12:05

@Hubert Roksor : :shock: :shock: effectivement tu as raison, ne comprenant pas très bien la requête je me suis juste contenté du résultat. Là je viens de tester et ça ne marche finalement pas.

Mon but est le suivant, j'ai ça :

Code : Tout sélectionner

------------------------------------------------- | Pays | Division | Equipe | Joueur | Salaire | ------------------------------------------------- | France | L1 | Equipe1 | toto | 100 | | France | L1 | Equipe1 | titi | 200 | | France | L1 | Equipe1 | tata | 300 | | France | L2 | Equipe1 | toto | 100 | | France | L2 | Equipe1 | titi | 200 | | France | L2 | Equipe1 | tata | 300 | | France | L3 | Equipe1 | toto | 500 | | France | L3 | Equipe1 | titi | 500 | | France | L3 | Equipe1 | tata | 500 | | Belgiq | D1 | Equipe1 | toto | 100 | | Belgiq | D1 | Equipe1 | titi | 200 | | Belgiq | D1 | Equipe1 | tata | 300 | -------------------------------------------------
et je veux executé une requete avec 3 parametres : le pays, la division et l'equipe.
qui me renvoi ça (exemple avec France,L1,Equipe1) :

Code : Tout sélectionner

----------------------------------------------- | Pays | Division | Equipe | REP_IDENTIQUE | ----------------------------------------------- | France | L1 | Equipe1 | VRAI | | France | L2 | Equipe1 | VRAI | | France | L3 | Equipe1 | FAUX | | Belgiq | D1 | Equipe1 | VRAI | -----------------------------------------------
Hubert, tu as bien compris qu'il faut que la répartition soit exactement la même
France,L2,Equipe1 est VRAI car
toto à le même salaire que toto de France,L1,Equipe1
ET
tata à le même salaire que toto de France,L1,Equipe1
ET
titi à le même salaire que toto de France,L1,Equipe1

saurais-tu m'aider ?


PS : merci car je n'avais vraiment pas vu ... :wink:

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

11 oct. 2007, 22:04

Ce n'est pas vraiment le genre de requêtes qu'on voit souvent, et SQL n'est pas très bien armé pour ce genre de comparaison, mais on peut toujours trouver des solutions. Tu n'as pas précisé quelle était la version de ton SGBD, donc tu auras peut-être à adapter/remplacer par du PHP.

Tu peux commencer par obtenir la "signature" des salaires de chaque équipe, sous la forme d'une chaîne représentant la liste des salaires par ordre croissant. Pour des raisons pratiques, je mets le tout dans une table temporaire (les tables temporaires s'auto-détruisent après usage)

Code : Tout sélectionner

CREATE TEMPORARY TABLE sigs SELECT Pays, Division, Equipe, GROUP_CONCAT(Salaire ORDER BY Salaire) AS sig FROM Table GROUP BY Pays, Division, Equipe
Ensuite à l'aide d'une auto-jointure on récupère la liste des autres équipes partageant la même signature

Code : Tout sélectionner

SELECT t2.Pays, t2.Division, t2.Equipe FROM sigs t1 JOIN sigs t2 USING (sig) WHERE t1.Equipe = 'Equipe1' AND ( t2.Pays <> t1.Pays OR t2.Division <> t2.Division OR t2.Equipe <> t2.Equipe )
Sinon, tu pourrais récupérer la signature de l'équipe choisie en PHP, puis exécuter une seconde requête pour trouver les autres équipes.

Code : Tout sélectionner

SELECT GROUP_CONCAT(Salaire ORDER BY Salaire) AS sig FROM Table WHERE Equipe = 'Equipe1'

Code : Tout sélectionner

SELECT Pays, Division, Equipe, GROUP_CONCAT(Salaire ORDER BY Salaire) AS sig FROM Table WHERE Equipe <> 'Equipe1' GROUP BY Pays, Division, Equipe HAVING sig = '100,200,300'

Eléphant du PHP | 443 Messages

11 oct. 2007, 23:05

Salut,

Sympathique group_concat comme fonction de regroupement, d'ailleurs je viens de faire un tour dans la documentation et j'en ai trouvé quelques autres. SQL Server, que j'ai plus l'habitude de manipuler, est bien moins riche de ce côté là...

Merci mister Roksor pour ces informations.
a+

Eléphanteau du PHP | 11 Messages

12 oct. 2007, 16:54

@Hubert Roksor : :agenouille: :agenouille:
je te remercie beaucoup de ta réponse (et encore merci d'avoir vu que la première réponse n'est pas la bonne).
J'ai choisi la 2ème soluce. Je fais 2 requêtes mais ça me convient très bien.

le GROUP_CONCAT je n'en avait même pas idée ! :D
(déjà la dernière fois tu m'avais sorti un COALESCE() de sous le chapeau)


grand merci à vous et à ce forum

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

12 oct. 2007, 17:07

le GROUP_CONCAT je n'en avait même pas idée ! :D
En fait c'est assez simple à découvrir. Quand tu as une heure à perdre, va lire le manuel au chapitre des fonctions et parcours-le dans l'ordre, sous-chapitre par sous-chapitre. Tu y trouveras des trucs intéressants, qui te reviendront en tête lorsque tu en auras besoin.

Bonne continuation.