IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Requêtes MySQL Discussion :

[requête] Topics où ont été postés les 10 derniers messages


Sujet :

Requêtes MySQL

  1. #1
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut [requête] Topics où ont été postés les 10 derniers messages
    Bonjour, Pour créer une partie "En directe du forum", je desirerais afficher les topics où ont été postés les derniers posts sans afficher 2 fois le même topics.

    Sur mon premier site ( version de mysql : 4.0.25) j'utilisais ce code qui marche très bien :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DISTINCT P.topic_id, T.tid, T.title, T.posts, T.forum_id, F.name, F.id FROM ibf_posts P 
    LEFT OUTER JOIN ibf_topics T ON P.topic_id = T.tid 
    LEFT OUTER JOIN ibf_forums F ON T.forum_id = F.id 
    WHERE T.forum_id !="22" GROUP BY P.pid  ORDER BY P.pid DESC LIMIT 0, 10
    Mais sur mon 2e site ( version mysql : 4.1.19) ça ne marche pas correctement: Cela affiche les derniers topics ajoutés.

    Quand j'ajoute

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT DISTINCT  P.topic_id, T.tid, T.title, T.posts, T.forum_id, F.name, F.id, P.pid FROM ibf_posts P 
    LEFT OUTER JOIN ibf_topics T ON P.topic_id = T.tid 
    LEFT OUTER JOIN ibf_forums F ON T.forum_id = F.id 
    WHERE T.forum_id !="9" GROUP BY P.pid  ORDER BY P.pid DESC LIMIT 0, 10
    Cela m'affiche bien les topics où ont été postés les dernier postes mais le DISTINCT de fonctionne plus, les mêmes topics sont affichés plusieurs fois.

    Merci d'avance.

  2. #2
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Bonjour,

    Une première remarque : pourquoi LEFT OUTER JOIN ? Il peut y avoir des posts non rattachés à un topic et des topics non rattachés à un forum ?

    Ensuite j'ai du mal à comprendre l'intérêt du GROUP BY P.pid puisque la requête est déjà censée sortir une seule ligne pour chacun des 10 derniers posts...
    Par contre un GROUP BY T.tid serait plus pertinent puisque tu veux avoir les topics où ont été postés les 10 derniers messages.

    Il faut bien voir que le DISTINCT fonctionne sur la ligne entière. Si deux lignes diffèrent ne serait-ce que par la valeur d'une colonne (comme c'est forcément le cas avec les P.pid de ta 2è requête), elles ne sont pas considérées comme des doublons. Donc ce n'est pas un DISTINCT qu'il te faut ici mais un regroupement par topic.

  3. #3
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    Mettre un INNER JOIN, ok.
    Ensuite ce que je ne comprend pas c'est pourquoi la première requête marche parfaitement pour le premier site et pas pour le 2e.
    Est-ce que tu pourrais me faire juste la structure de la requête STP. J'ai un peu de mal à savoir ou j'en suis. Merci

  4. #4
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par sawati
    Ensuite ce que je ne comprend pas c'est pourquoi la première requête marche parfaitement pour le premier site et pas pour le 2e.
    Je ne sais pas. Si les données contenues dans les 2 bases sont les mêmes il n'y a absolument aucune raison que ça fonctionne avec l'une et pas l'autre.

    Citation Envoyé par sawati
    Est-ce que tu pourrais me faire juste la structure de la requête STP. J'ai un peu de mal à savoir ou j'en suis. Merci
    Quelque chose du style
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    SELECT P.topic_id, T.tid, T.title, T.posts, T.forum_id, F.name, F.id FROM ibf_posts P 
    INNER JOIN ibf_topics T ON P.topic_id = T.tid 
    INNER JOIN ibf_forums F ON T.forum_id = F.id 
    WHERE T.forum_id !="22" 
    GROUP BY T.tid  
    ORDER BY P.pid DESC LIMIT 10

  5. #5
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    Cette requête m'affiche le 10 derniers topics ajoutés. Je comprend plus rien

  6. #6
    Membre éprouvé
    Avatar de Biglo
    Profil pro
    Inscrit en
    Juillet 2002
    Messages
    537
    Détails du profil
    Informations personnelles :
    Localisation : France, Moselle (Lorraine)

    Informations forums :
    Inscription : Juillet 2002
    Messages : 537
    Points : 984
    Points
    984
    Par défaut
    Donne-nous la structure des trois tables. Ca sera plus simple.

  7. #7
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    `ibf_posts` (
    `pid` int(10) NOT NULL auto_increment,
    `append_edit` tinyint(1) default '0',
    `edit_time` int(10) default NULL,
    `author_id` mediumint(8) NOT NULL default '0',
    `author_name` varchar(32) default NULL,
    `use_sig` tinyint(1) NOT NULL default '0',
    `use_emo` tinyint(1) NOT NULL default '0',
    `ip_address` varchar(16) NOT NULL default '',
    `post_date` int(10) default NULL,
    `icon_id` smallint(3) default NULL,
    `post` text,
    `queued` tinyint(1) NOT NULL default '0',
    `topic_id` int(10) NOT NULL default '0',
    `post_title` varchar(255) default NULL,
    `new_topic` tinyint(1) default '0',
    `edit_name` varchar(255) default NULL,
    `post_key` varchar(32) NOT NULL default '0',
    `post_parent` int(10) NOT NULL default '0',
    `post_htmlstate` smallint(1) NOT NULL default '0',
    PRIMARY KEY (`pid`),
    KEY `topic_id` (`topic_id`,`queued`,`pid`),
    KEY `author_id` (`author_id`,`topic_id`),
    KEY `post_date` (`post_date`),
    FULLTEXT KEY `post` (`post`)
    )

    `ibf_topics` (
    `tid` int(10) NOT NULL auto_increment,
    `title` varchar(250) NOT NULL default '',
    `description` varchar(70) default NULL,
    `state` varchar(8) default NULL,
    `posts` int(10) default NULL,
    `starter_id` mediumint(8) NOT NULL default '0',
    `start_date` int(10) default NULL,
    `last_poster_id` mediumint(8) NOT NULL default '0',
    `last_post` int(10) default NULL,
    `icon_id` tinyint(2) default NULL,
    `starter_name` varchar(32) default NULL,
    `last_poster_name` varchar(32) default NULL,
    `poll_state` varchar(8) default NULL,
    `last_vote` int(10) default NULL,
    `views` int(10) default NULL,
    `forum_id` smallint(5) NOT NULL default '0',
    `approved` tinyint(1) NOT NULL default '0',
    `author_mode` tinyint(1) default NULL,
    `pinned` tinyint(1) default NULL,
    `moved_to` varchar(64) default NULL,
    `total_votes` int(5) NOT NULL default '0',
    `topic_hasattach` smallint(5) NOT NULL default '0',
    `topic_firstpost` int(10) NOT NULL default '0',
    `topic_queuedposts` int(10) NOT NULL default '0',
    `topic_open_time` int(10) NOT NULL default '0',
    `topic_close_time` int(10) NOT NULL default '0',
    `topic_rating_total` smallint(5) unsigned NOT NULL default '0',
    `topic_rating_hits` smallint(5) unsigned NOT NULL default '0',
    PRIMARY KEY (`tid`),
    KEY `topic_firstpost` (`topic_firstpost`),
    KEY `last_post` (`forum_id`,`pinned`,`last_post`),
    KEY `forum_id` (`forum_id`,`pinned`,`approved`),
    FULLTEXT KEY `title` (`title`)
    )

    `ibf_forums` (
    `id` smallint(5) NOT NULL default '0',
    `topics` mediumint(6) default NULL,
    `posts` mediumint(6) default NULL,
    `last_post` int(10) default NULL,
    `last_poster_id` mediumint(8) NOT NULL default '0',
    `last_poster_name` varchar(32) default NULL,
    `name` varchar(128) NOT NULL default '',
    `description` text,
    `position` tinyint(2) default NULL,
    `use_ibc` tinyint(1) default NULL,
    `use_html` tinyint(1) default NULL,
    `status` tinyint(1) default '1',
    `password` varchar(32) default NULL,
    `last_title` varchar(128) default NULL,
    `last_id` int(10) default NULL,
    `sort_key` varchar(32) default NULL,
    `sort_order` varchar(32) default NULL,
    `prune` tinyint(3) default NULL,
    `topicfilter` varchar(32) NOT NULL default 'all',
    `show_rules` tinyint(1) default NULL,
    `preview_posts` tinyint(1) default NULL,
    `allow_poll` tinyint(1) NOT NULL default '1',
    `allow_pollbump` tinyint(1) NOT NULL default '0',
    `inc_postcount` tinyint(1) NOT NULL default '1',
    `skin_id` int(10) default NULL,
    `parent_id` mediumint(5) default '-1',
    `quick_reply` tinyint(1) default '0',
    `redirect_url` varchar(250) default '',
    `redirect_on` tinyint(1) NOT NULL default '0',
    `redirect_hits` int(10) NOT NULL default '0',
    `redirect_loc` varchar(250) default '',
    `rules_title` varchar(255) NOT NULL default '',
    `rules_text` text NOT NULL,
    `topic_mm_id` varchar(250) NOT NULL default '',
    `notify_modq_emails` text,
    `sub_can_post` tinyint(1) default '1',
    `permission_custom_error` text NOT NULL,
    `permission_array` mediumtext NOT NULL,
    `permission_showtopic` tinyint(1) NOT NULL default '0',
    `queued_topics` mediumint(6) NOT NULL default '0',
    `queued_posts` mediumint(6) NOT NULL default '0',
    `forum_allow_rating` tinyint(1) NOT NULL default '0',
    `forum_last_deletion` int(10) NOT NULL default '0',
    PRIMARY KEY (`id`),
    KEY `position` (`position`,`parent_id`)
    )

    Voilà tout est là

  8. #8
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    Donc alors il faudrait faire un regroupemment sur la tables des posts par le champ 'P.topic_id' , mais comment le faire sur cette table là ?

  9. #9
    Membre émérite Avatar de Maximil ian
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    2 622
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 2 622
    Points : 2 973
    Points
    2 973
    Par défaut
    Citation Envoyé par sawati
    Cette requête m'affiche le 10 derniers topics ajoutés. Je comprend plus rien
    Heu, chez moi ça fonctionne très bien
    Peut-être que ces topics correspondent justement à ceux où ont été postés les derniers messages ?

  10. #10
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    Non, j'ai bien vérifier. Cela indique bien les 10 derniers topics ajoutés . Est-ce que ça pourrait venir d'un problème du serveur Mysql ? ( version mysql : 4.1.19)

  11. #11
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    C'est une théorie, mais s'il y a plusieurs posts pour un topic, on groupe par topic en triant sur les post... mais après le regroupement on ne sait pas quel post va être retenu pour un topic donné. Bref mieux vaut ne pas compter sur "P.pid".

    Est-ce que ceci passe mieux ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    SELECT P.topic_id, T.tid, T.title, T.posts, T.forum_id, F.name, F.id
    FROM ibf_posts P INNER JOIN ibf_topics T ON P.topic_id = T.tid
                     INNER JOIN ibf_forums F ON T.forum_id = F.id
    WHERE T.forum_id != "22"
    GROUP BY T.tid
    ORDER BY MAX(P.pid) DESC LIMIT 10

  12. #12
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    Ta requête m'affiche cette erreur : Invalid use of group function

  13. #13
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Désolé, ça semble nécessiter mysql 5
    Pourtant j'aurais cru...

    Alors dans l'idée on "pourrait" utiliser (si j'ai pas fait de faute de frappe, le concept marche sur ma 4.1.7) :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    SELECT P1.pid, P1.topic_id, T.tid, T.title, T.posts, T.forum_id, F.name, F.id
    FROM ibf_topics T INNER JOIN ibf_forums F ON T.forum_id = F.id
                      INNER JOIN ibf_posts P1 ON P1.topic_id = T.tid
                      INNER JOIN ibf_posts P2 ON P2.topic_id = T.tid     
    WHERE T.forum_id != "22"
    GROUP BY T.tid, P1.pid
    HAVING P1.pid=MAX(P2.pid)
    ORDER BY P1.pid DESC LIMIT 10
    mais c'est moche pour les performances, alors en première page d'un forum je ne le sens pas (avec de bons indexes ?).

    Sans changer pour mysql 5 la meilleur solution sera probablement de sortir les topic avec leur MAX(pid) et de trier via PHP ou quoi que ce soit qu'utilise le forum. Ou peut-être mieux prendre les, disons, 50 derniers post et utiliser du code pour attraper les 10 premiers topics là dedans.

    Edit : P1.pid est listé même s'il ne sert pas car en dessous de mysql 5 le requête est refusée sans cela.

  14. #14
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    Unknown column 'P1.pid' in 'having clause'

  15. #15
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Ben je viens d'apprendre un truc sur HAVING : il faut ajouter 'P1.pid' dans les champs listés sinon il ne le trouve pas (dsl, j'avais testé le concept sur une table qui trainait chez moi).

    J'édite mon post précédent.

  16. #16
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    Autre idée assez simple : mettre un champ dans les topic pour conserver le numéro ou la date du dernier post. Le mettre à jour est assez simple et le problème des topics les plus à jour devient alors trivial.

  17. #17
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    Merci ! ta requête marche à merveille. Il reste un truc qui m'embête :

    Si je reprend mon ancienne requête :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    SELECT DISTINCT P.topic_id, T.tid, T.title, T.posts, T.forum_id, F.name, F.id 
    FROM ibf_posts P 
    INNER JOIN ibf_topics T ON P.topic_id = T.tid 
    INNER JOIN ibf_forums F ON T.forum_id = F.id 
    WHERE T.forum_id !="22" 
    GROUP BY P.pid  
    ORDER BY P.pid 
    DESC LIMIT 0, 10
    Sur l'ancien serveur il marchait très bien

    Si j'enlève le DISTINCT : Cela m'affiche les derniers Topics où ont été posté sles derniers posts mais en affichant plusieurs fois les mêmes topics, le DISTINCT n'est pas censé éliminer les doublons sur toute une ligne ?

  18. #18
    Membre éprouvé
    Avatar de Sivrît
    Profil pro
    Inscrit en
    Février 2006
    Messages
    953
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Février 2006
    Messages : 953
    Points : 1 249
    Points
    1 249
    Par défaut
    D'après ce que j'ai vu dans la doc DISTINCT marche comme un GROUP BY sur les champs sélectionnés. Donc trier sur un champ pour lequel plusieurs valeurs ont été regroupées donne un résultat indéterminé : si on affichait 'P.pid' on aurait l'un des 'pid' regroupés... sans savoir à l'avance lequel. Donc pour un tri c'est pas l'extase. En triant sur 'MAX(P.pid)' ça serait parfait mais pas en 4

    J'ai fait un essai sur une table minimaliste avec un DISTINCT et le tri sur les champs non affichés (et donc regroupés) n'est pas fiable. Avec de la chance la mécanique interne peut faire marcher le tri si les bons pid sortent (c'est un peu le loto !), mais recharger la base ailleurs peut changer l'ordre de stockage et tout mettre par terre.

    Il est 'possible' (lire 'imaginable') que l'insertion des posts en fin de table combiné avec le fonctionnement du GROUP BY (ou DISTINCT) donne le premier post en partant de la fin avec une certaine version de MySQL, et qu'une autre parte du début, ou que le transport de la table ai changé l'ordre interne. A moins qu'un index ne joue ?

    Est-ce que l'ordre sur l'ancien serveur était bon tout le temps, ou alors "crédible", ou encore "vérifié une fois et c'était bon" ?

  19. #19
    Membre à l'essai
    Profil pro
    Inscrit en
    Juin 2006
    Messages
    45
    Détails du profil
    Informations personnelles :
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations forums :
    Inscription : Juin 2006
    Messages : 45
    Points : 13
    Points
    13
    Par défaut
    J'ai vérifié, l'ordre est bon.

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/02/2014, 12h41
  2. Réponses: 39
    Dernier message: 21/03/2011, 13h51
  3. Réponses: 8
    Dernier message: 25/01/2011, 09h23

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo