Page 1 sur 1

Optimisation SQL pour soulager le script PHP

Posté : 20 mars 2007, 18:15
par Invité
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 !

Posté : 20 mars 2007, 18:53
par raptor
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
@+

Posté : 20 mars 2007, 19:10
par Invité
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 ...

Posté : 20 mars 2007, 23:11
par ghalaad

Code : Tout sélectionner

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

Posté : 21 mars 2007, 11:31
par Invité
non, cela ne marche pas du tout.

Posté : 21 mars 2007, 22:34
par ghalaad
Exact, j'ai écrit trop vite... Il faut regrouper par code :
SELECT MAX(version),... FROM table GROUP BY code

Posté : 22 mars 2007, 00:16
par Ryle
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 :)

Posté : 22 mars 2007, 04:18
par ghalaad
[edit]
Ca foire sous Oracle effectivement ;)

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

Posté : 22 mars 2007, 09:46
par Invité
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