requete MySQL

Discussion dans 'Web, design' créé par Calvin80, 14 Avril 2006.

Statut de la discussion:
Fermée.
  1. Offline
    Calvin80 Elite
    Bonjour à tous..
    J'ai une requete mysql à faire, qui parait débile et pourtant, elle ressort pas ce que je voudrais.

    Il s'agit d'une table album photo, dont les champs sont:
    - id: identifiant de la photo (clef primaire de la table, auto_increment)
    - user_id: l'utilsateur possedant la photo
    - added: la date à laquelle la photo a été ajoutée.

    voila, c'est plutot un table simple...

    Je veux recuperer les utilisateurs DISTINCS des 10 dernieres photos postées.

    j'ai donc essayer:
    "SELECT DISTINCT (user_id), id, added FROM albumphoto ORDER BY added DESC LIMIT 10";

    ca marche pas (voila ce que ça me ressort)
    Code:
    204 	548 	2006-04-13 23:36:50
    204 	547 	2006-04-13 23:27:34
    204 	546 	2006-04-13 23:26:29
    204 	545 	2006-04-13 23:17:13
    204 	544 	2006-04-13 23:11:20
    863 	543 	2006-04-12 16:34:22
    859 	542 	2006-04-12 15:25:56
    859 	541 	2006-04-12 15:25:36
    859 	540 	2006-04-12 15:25:17
    859 	539 	2006-04-12 15:25:02
    
    maintenant si j'essaie la meme requete sans le "added" et le "id" dans le select:
    Code:
    863
    859
    838
    831
    785
    833
    828
    707
    815
    
    cette fois on a bien des user_id distintcs, mais ils ston pas classés par date !!! ??? !!!

    bon je vais regarder le manual mysql, mais si vous avez des idées.... merci
    Calvin80, 14 Avril 2006
    #1
  2. Offline
    null ose();
    LIMIT s'utilise : LIMIT debut,fin donc :

    Mais je sais pas si ça va résoudre ton problème
    null, 14 Avril 2006
    #2
  3. Offline
    Calvin80 Elite
    Hello
    merci pour ta réponse.
    LIMIT peut s'utiliser avec les deux syntaxes, le problème ne se situe maleuhreusement pas là.
    Calvin80, 14 Avril 2006
    #3
  4. Offline
    null ose();
    Ha je ne savais pas, merci :]
    null, 14 Avril 2006
    #4
  5. Offline
    II phl II Touriste
    c'est cette requête qui te retourne les user_id mais ds le mauvais ordre ?
    Code:
    "SELECT DISTINCT (user_id) FROM albumphoto ORDER BY added DESC LIMIT 10";
    Pourtant ça devrait aller :?:
    II phl II, 14 Avril 2006
    #5
  6. Offline
    Calvin80 Elite
    oui ça devrait... et je m'inquiete fort que ça ne marche pas..
    ce qui me fat le + peur, c'est que 'jai utilisé ce genre de requete (distinct) des 100aines de fois....
    Calvin80, 14 Avril 2006
    #6
  7. Offline
    Ghost Glider Elite
    Dans ta query :
    "SELECT DISTINCT (user_id), id, added FROM albumphoto ORDER BY added DESC LIMIT 10";

    Les parenthèses autour de user_id ne servent à rien car le distinct porte sur tes 3 champs et non pas uniquement sur user_id.

    Si tu regardes point de vu records ils sont chaque fois unique!
    Ghost Glider, 14 Avril 2006
    #7
  8. Offline
    Calvin80 Elite
    Cette requete n'est pas la bonne, ça OK. Mais elle vous montre que, le premier enregistrement que doit vous retourner la bonne requete est :
    "204"


    et je n'arrive pas à trouver la bonne requete.
    Calvin80, 14 Avril 2006
    #8
  9. Offline
    FoX SpeEd Touriste
    bon vu que les id sont auto incrementer c'est a dire que l'id le plus grand vaut obligatoirement la derniere photo aujouter ok? donc essaye une foi de les trier selon leur id au lieu de la date. Peut etre qu'il ne le gere pas bien v'est tout :wink:
    FoX SpeEd, 14 Avril 2006
    #9
  10. Offline
    Calvin80 Elite
    bon ça y'est j'ai trouvé cette foutue requete :

    Code:
    SELECT user_id, MAX(added) as m FROM albumphoto GROUP BY user_id ORDER BY m DESC;
    
    Calvin80, 14 Avril 2006
    #10
  11. Online
    BOZO ex membre
    Fallait le savoir :twisted:
    BOZO, 14 Avril 2006
    #11
  12. Offline
    Calvin80 Elite
    c'est clair...
    surtout quil y a un truc que je n'expliqe pas, car si je fais la requete sur les id (comme l'a bien suggéré Fox Speed):
    Code:
    SELECT DISTINCT(user_id) FROM albumphoto ORDER BY id DESC LIMIT 10;
    
    la ca marche.., ça me renvoie :
    Code:
    204
    863
    859
    ...
    
    et la meme sur la date, ca marche plus
    Code:
    SELECT DISTINCT(user_id) FROM albumphoto ORDER BY id DESC LIMIT 10;
    
    ça me renvoie :
    Code:
    863
    859
    ...
    
    ce qui n'est pas bon
    Et poutant les id sont dans le meme ordre que la date...

    Edit: oops j'ai oublié le principal : merci à tous pour vos suggestions !
    Calvin80, 14 Avril 2006
    #12
  13. Offline
    FoX SpeEd Touriste
    bete question

    la date tu la mit dans ta table avec la fonction mysql adequate ou via le script php donc la fonction en php?

    si c'est la 2eme solution c'est normal
    et puis si tu ne veut plus d'enmerde utilise alors le timestamp :wink:
    FoX SpeEd, 14 Avril 2006
    #13
  14. Offline
    Calvin80 Elite
    je l'ai mis via un mysql_query() (php).
    mais je comprends pas ton "c'est normal".

    j'ai fait le test avec un timestamp: meme problème
    Calvin80, 14 Avril 2006
    #14
  15. Offline
    Bingo Beer Addict
    Le problème de ta requête c'est la clause LIMIT.
    Si tu utilises une clause "LIMIT x" avec une clause DISTINCT, MySQL arrête la requête dès qu'il a trouvé x valeurs distinctes.
    Après seulement il les trie. Du coup le résultat est imprévisible.

    Dans ce cas le GROUP BY est effectivement plus approprié.
    Bingo, 14 Avril 2006
    #15
  16. Offline
    Calvin80 Elite
    Hello Bingo..
    je reste dubitatif, je vois pas en quoi le limit va faier foirer le tri..

    je vais tester sans limit pour voir.


    Edit: meme problème sans le "LIMIT"
    Calvin80, 14 Avril 2006
    #16
  17. Offline
    Bingo Beer Addict
    Le tri est la dernière opération : MySQL parcourt la table à la recherche de valeurs distinctes de user_id. Dès qu'il en a 10 (ta limite), il s'arrête de parcourir la table. Après seulement il trie les résultats.

    Je crois qu'il y a un chapitre là-dessus dans le manuel MySQL.
    Bingo, 14 Avril 2006
    #17
  18. Offline
    Calvin80 Elite
    ha ok j'ai compris ce que tu voulais dire !!!
    Calvin80, 14 Avril 2006
    #18
  19. Offline
    Calvin80 Elite
    Bon.... je vais essayer de recapituler le problème et ses solutions (j'aime bien les récapitulatifs, ça me remet les idées au clair).

    Considérons la table suivante :
    Code:
    id   	 user   	 date
    1 	1 	2001-01-01 00:00:00
    2 	1 	2002-01-01 00:00:00
    3 	2 	2003-01-01 00:00:00
    4 	3 	2002-01-01 00:00:00
    5 	1 	2005-01-01 00:00:00
    
    la clef primaire est"id" (auto incrementale).

    But :Récuperer les utilisateurs (champs 'users') distincts ET triés par dates, de la plus nouvelle (ou "grande" en terme de comparaison de dates) à la plus ancienne..
    Le résulat est evident: c'est le user 1 puis le user 2 puis le user 3 (dans cette ordre). La requête semble à prori évidente, pourtant elle est pas si "simple" que ça...

    Voyons les requêtes possibles et leurs résultats

    Requête #1
    Code:
    SELECT user FROM test ORDER BY date DESC;
    
    qui renvoie
    Code:
    user
    1
    1
    2
    3
    1
    
    les utilisateurs sont donc bien classés par date, mais l'utilisateur 1 est répété plusieurs fois.
    On va donc utiliser la syntaxe DISTINCT


    Requête #2
    Code:
    SELECT DISTINCT(user) FROM test ORDER BY date DESC;
    
    Personnellement, je m'attendais à avoir le bon résultat, et pourant, ça renvoie :
    Code:
    user
    2
    3
    1
    
    Pourquoi ?
    Mysql va parcourir la table :

    • 1iere entrée :"1 1 2001-01-01", elle correspond à la requête, elle est mise dans la pile de résultats.
      2ieme entrée: "2 1 2004-01-01", NE correspond PAS à la requête car l'utilisateur 1 est deja présent dans la pile de résultat, et la requête demandais du distinct.
      3ieme entrée: "3 2 2003-01-01", elle correspond à la requête, elle est mise dans la pile de résultats.
      4ieme entrée: "4 3 2002-01-01", elle correspond à la requête, elle est mise dans la pile de résultats.
      5ieme entrée: "5 1 2005-01-01" ne répond pas à la requête pour les mêmes raisons que la 2ieme entrée.
    La pile résultats est donc
    Code:
    id   	 user   	 date
    1 	1 	2001-01-01 00:00:00
    3 	2 	2003-01-01 00:00:00
    4 	3 	2002-01-01 00:00:00
    
    Mysql va appliquer le "ORDER BY date"
    Code:
    id   	 user   	 date
    3 	2 	2003-01-01 00:00:00
    4 	3 	2002-01-01 00:00:00
    1 	1 	2001-01-01 00:00:00
    
    d'où sont résultats.
    Alors comment faire ?

    Requête #3
    Code:
    SELECT user, max(date) as m FROM test GROUP BY user ORDER BY m DESC;
    
    Cette requête renvoie ce qu'on esperait:
    Code:
    user
    1
    2
    3
    
    Pourquoi ?
    Mysql va parcourir la table ;

    • 1iere entrée :"1 1 2001-01-01", elle correspond à la requête, elle est mise dans la pile de résultats
      2ieme entrée: "2 1 2004-01-01", correspond à la requête,
      elle va ecraser la 1ire entrée dans la pile résultat, car on demande le "MAX(date)" et que cette date est plus grande que celle de la pile.
      3ieme entrée: "3 2 2003-01-01", elle correspond à la requête, elle est mise dans la pile de résultats
      4ieme entrée: "4 3 2002-01-01", elle correspond à la requête, elle est mise dans la pile de résultats
      5ieme entrée: "5 1 2005-01-01" ne répond pas à la requête, elle va ecraser la 1ire entrée dans la pile résultat, car on demande le "MAX(date)" et que cette date est plus grande que celle de la pile.

    La pile de résultat est donc:
    Code:
    id   	 user   	 date
    5 	1 	2005-01-01 00:00:00
    3 	2 	2003-01-01 00:00:00
    4 	3 	2002-01-01 00:00:00
    
    MySQL va alors appliquer le "ORDER BY date" (la pile est deja triées par date, mais cest du hasard), puis va renvoyer le résultat.

    Voila, la requête #3 etait donc la requête que je cherchais :).
    Calvin80, 14 Avril 2006
    #19
  20. Offline
    Bingo Beer Addict
    Arf, ça c'est de la récapitulation ! ;)
    Bingo, 14 Avril 2006
    #20
Statut de la discussion:
Fermée.