Optimisation SQL pour soulager le script PHP

Invité
Invité n'ayant pas de compte PHPfrance

20 mars 2007, 18:15

Bonjour à tous!

Alors voila une table element dont voici la structure:

Image

Je souhaiterai obtenir, en une seule requête, la version la plus haute de chaque code, soit le résultat suivant:

Image

Pour le moment je me contente d'un SELECT * FROM element que je traite ensuite via PHP pour ne garder que la version la plus haute de chaque code.

Merci !

Mammouth du PHP | 543 Messages

20 mars 2007, 18:53

Tiens, une version possible :

Code : Tout sélectionner

SELECT e.code,e.id,e.version,e.detail FROM element e JOIN (SELECT version,code,id FROM element ORDER BY code ASC, version DESC) f ON f.version=e.version AND f.code=e.code GROUP BY code
@+

Invité
Invité n'ayant pas de compte PHPfrance

20 mars 2007, 19:10

raptor n'était pas loin ... voila la réponse:

Code : Tout sélectionner

SELECT e. * FROM element AS e JOIN ( SELECT code, MAX( version ) AS version FROM element GROUP BY code ) AS f ON f.version = e.version AND f.code = e.code
Merci de m'avoir mis sur la voie. Un JOIN qui utilise une sélection au lieu d'une table, c'est subtile 8-)

Si un admin pouvait mettre le tag résolu ...

Eléphanteau du PHP | 49 Messages

20 mars 2007, 23:11

Code : Tout sélectionner

SELECT MAX(version),... FROM table GROUP BY version
aurait aussi très bien marché :)

Invité
Invité n'ayant pas de compte PHPfrance

21 mars 2007, 11:31

non, cela ne marche pas du tout.

Eléphanteau du PHP | 49 Messages

21 mars 2007, 22:34

Exact, j'ai écrit trop vite... Il faut regrouper par code :
SELECT MAX(version),... FROM table GROUP BY code

Avatar du membre
Modérateur PHPfrance
Modérateur PHPfrance | 10684 Messages

22 mars 2007, 00:16

Dans le group by il faut mettre tous les éléments du select auxquels aucune fonction de groupe n'a été appliquée :

Code : Tout sélectionner

SELECT MAX(version), [...] FROM table GROUP BY [...]
S'il n'y a que le champ code dans les [...], tu auras effectivement chaque code regroupé (comme un distinct), associé a sa version max. Le problème c'est que si tu ajoutes le champ detail, comme il semble en avoir besoin, il te faut grouper par code et detail. Et comme la majorité des couples code/détail seront différents, il se retrouvera avec tous les enregistrements

En y réflechissant, mysql permet peut être de ne pas mettre tous les champs dans le group by, mais ce serait vraiment spécifique à cette base, et j'ai pas la moindre idée du résultat que cela pourrait produire :)
Ce n'est pas en améliorant la bougie que l'on a inventé l'ampoule...

Eléphanteau du PHP | 49 Messages

22 mars 2007, 04:18

[edit]
Ca foire sous Oracle effectivement ;)

Par contre ça marche très bien sous MySQL.

Invité
Invité n'ayant pas de compte PHPfrance

22 mars 2007, 09:46

ghalaad, ta requête ne marche pas non plus sous mysql

Code : Tout sélectionner

SELECT id, code, MAX( version ) version, detail FROM element GROUP BY code
voila le résultat:

Image

les champs id et detail ne sont pas les bons!

alors que cette requête:

Code : Tout sélectionner

SELECT e.* FROM element AS e JOIN ( SELECT code, MAX( version ) AS version FROM element GROUP BY code ) AS f ON f.version = e.version AND f.code = e.code
renvoi bien le résultat voulu:

Image