[MySQL] Jointures externes et dernier enregistrement

Modérateur PHPfrance
Modérateur PHPfrance | 6037 Messages

09 juin 2006, 12:24

Bonjour,

Je suis sous MYSQL 4

Les experts SQL présents sur ce forum, et tout autre cerveau disponible est le bienvenu.
J'ai une application avec des fiches pour chaque personne, et je peux ajouter des augmentations à chaque personne. Autant que je veux.
Pour un export des données (impression) je souhaite n'avoir qu'une augmentation par personne, la dernière insérée.

Voici ce que j'ai dans ma base :
table profil (id, nom, prenom, ...)
table salaire (id, id_profil, augmentation_type)

En plus, je stocke le pays, le poste et autres données dans des tables externes.

Voici ce que je veux obtenir :

Mr DUPONT Jean, France, directeur, augmentation salariale
Mr LAFAILLE Marc, France, commercial, commission
Mr BLOBLO Paul, France, assistant, voiture de fonction

Ma requete actuelle :
SELECT p.id AS id_profil,
p.nom AS NOM,
p.prenom AS PRENOM,
poste.nom as POSTE,
pays.libelle as PAYS,
sal.aug_type AS AUG_TYPE,
MAX( sal.id_salaire ) AS max_id_salaire
FROM profil AS p
LEFT OUTER JOIN postes AS poste ON poste.id = p.poste_id
RIGHT OUTER JOIN salaire_manager AS sal ON sal.id_profil = p.id AND sal.id_salaire = MAX(sal.id_salaire )
LEFT OUTER JOIN pays AS pays ON pays.id = p.pays
WHERE p.anciennete_groupe_date >= '0-0-0'
AND p.anciennete_groupe_date <= '2006-06-09'
GROUP BY p.id, id_salaire
ORDER BY p.id ASC


Ce qu'elle retourne :

Les nom, prénom, postes, tout va bien, le max_id_salaire aussi, mais le aug_type, ça ne colle pas : ce n'est pas celui du max_id_salaire.


Comment faire pour avoir l'augmentation type correspondant à l'id_max_augmentation ?
Règle n°2 du webmaster : Toujours commencer par le HTML qu'on veut obtenir....toujours ! :priere:
J'aime apprendre de nouvelles choses.

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

09 juin 2006, 12:45

Je suis à la bourre donc je n'aurai pas le temps d'expliquer tout de suite, mais je repasserai ce soir sur le thread.

Si ta version de MySQL le permet (je dirais qu'il faut 4.1) il te faudrait utiliser une table dérivée pour récupérer chaque profil avec l'id maximum qui lui est associée. Quelque chose comme:

Code : Tout sélectionner

SELECT p.id AS id_profil, p.nom AS NOM, p.prenom AS PRENOM, poste.nom as POSTE, pays.libelle as PAYS, sal.aug_type AS AUG_TYPE FROM ( SELECT MAX(id) AS max_id_salaire, id_profil FROM salaire_manager GROUP BY id_profil ) AS aug JOIN profil AS p ON p.id = aug.id_profil LEFT OUTER JOIN postes AS poste ON poste.id = p.poste_id LEFT OUTER JOIN pays AS pays ON pays.id = p.pays WHERE p.anciennete_groupe_date >= '0-0-0' AND p.anciennete_groupe_date <= '2006-06-09' ORDER BY p.id ASC
Si tu utilises MySQL 4.0, crées une table temporaire et remplie-la comme le serait la table dérivée ci-dessus:

Code : Tout sélectionner

CREATE TEMPORARY TABLE aug ( max_id_salaire INT, id_profil INT ); INSERT INTO aug SELECT MAX(id) AS max_id_salaire, id_profil FROM salaire_manager GROUP BY id_profil; SELECT p.id AS id_profil, p.nom AS NOM, p.prenom AS PRENOM, poste.nom as POSTE, pays.libelle as PAYS, sal.aug_type AS AUG_TYPE FROM aug JOIN profil AS p ON p.id = aug.id_profil LEFT OUTER JOIN postes AS poste ON poste.id = p.poste_id LEFT OUTER JOIN pays AS pays ON pays.id = p.pays WHERE p.anciennete_groupe_date >= '0-0-0' AND p.anciennete_groupe_date <= '2006-06-09' ORDER BY p.id ASC

Modérateur PHPfrance
Modérateur PHPfrance | 6037 Messages

09 juin 2006, 12:52

J'espérais que les jointures viendraient à bout de mon souci :( mais la version en prod est 4.0.20, donc on va passer par le table temporaire.
Règle n°2 du webmaster : Toujours commencer par le HTML qu'on veut obtenir....toujours ! :priere:
J'aime apprendre de nouvelles choses.

Eléphant du PHP | 140 Messages

09 juin 2006, 15:35

J'espérais que les jointures viendraient à bout de mon souci :( mais la version en prod est 4.0.20, donc on va passer par le table temporaire.
De maniere generale, mon expert Oracle te dirait que ta requete portant sur un MAX dans la table des salaires, il te faut demarrer par cette table dans ta requete et faire des JOIN dessus.
En effet, des que tu utilises des OUTER JOIN, il est tres facile de joindre des trucs que l'on ne veut pas et oublier d'en joindre d'autres :?

C'est clair ce que j'ai ecrit ? :roll:

Modérateur PHPfrance
Modérateur PHPfrance | 6037 Messages

12 juin 2006, 10:24

C'est clair.
Je progresse en bdd chaque jour.
Règle n°2 du webmaster : Toujours commencer par le HTML qu'on veut obtenir....toujours ! :priere:
J'aime apprendre de nouvelles choses.