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 PostgreSQL Discussion :

Construction d'un arbre - récursivité


Sujet :

Requêtes PostgreSQL

  1. #1
    Membre éprouvé
    Avatar de Gecko
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Décembre 2008
    Messages
    499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Décembre 2008
    Messages : 499
    Points : 1 277
    Points
    1 277
    Par défaut Construction d'un arbre - récursivité
    Bonjour!

    J'ai un souci avec ma requête SQL:
    Code SQL : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    		WITH RECURSIVE children(nid,date,cid,parent,content,uid,level) AS (
    			SELECT nc.news_id,nc.comment_pubdate,nc.comment_id,nc.comment_parent,nc.comment_content,nc.user_id, 1
    			    FROM toine.news_comments nc
    			    WHERE nc.news_id = :news_id
    		    UNION ALL
    			SELECT news_id,comment_pubdate,comment_id,comment_parent,comment_content,user_id, e.level+1
    			    FROM toine.news_comments nc, children e
    			    WHERE nc.comment_parent = e.cid
    		)
    		SELECT * FROM children ORDER BY cid

    Les résultats ressortent plusieurs fois ce qui est embêtant. J'ai tenté d'ajouter GROUP BY mais ça me demande d'ajouter tous les arguments de children().

    Du coup je sèche un peu, le but est d'éviter d'avoir plusieurs requêtes pour afficher une liste de commentaires.

    Merci d'avance pour votre aide
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($toBe || !$toBe) echo 'That is the question';

    Mes projets: DVP I/O

  2. #2
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    S'il s'agit d'un GROUP BY sur toutes les colonnes, autant utiliser un DISTINCT...
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  3. #3
    Membre éprouvé
    Avatar de Gecko
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Décembre 2008
    Messages
    499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Décembre 2008
    Messages : 499
    Points : 1 277
    Points
    1 277
    Par défaut
    Citation Envoyé par al1_24 Voir le message
    S'il s'agit d'un GROUP BY sur toutes les colonnes, autant utiliser un DISTINCT...
    Ca ne change rien

    Je veut juste éliminer les doublons générés par la requête, je ne cherche pas forcément à traiter toutes les colonnes.

    Je comprend pas pourquoi j'ai ce comportement
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($toBe || !$toBe) echo 'That is the question';

    Mes projets: DVP I/O

  4. #4
    Modérateur
    Avatar de al1_24
    Homme Profil pro
    Retraité
    Inscrit en
    Mai 2002
    Messages
    9 080
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 63
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Retraité
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mai 2002
    Messages : 9 080
    Points : 30 803
    Points
    30 803
    Par défaut
    Si DISTINCT ne regroupe pas les lignes, il ne s'agit donc pas de doublons complet.
    La première chose à faire est de trouver la règle qui permettra d'identifier les lignes à conserver.
    Modérateur Langage SQL
    Règles du forum Langage SQL à lire par tous, N'hésitez pas à consulter les cours SQL
    N'oubliez pas le bouton et pensez aux balises
    [code]
    Si une réponse vous a aidé à résoudre votre problème, n'oubliez pas de voter pour elle en cliquant sur
    Aide-toi et le forum t'aidera : Un problème exposé sans mentionner les tentatives de résolution infructueuses peut laisser supposer que le posteur attend qu'on fasse son travail à sa place... et ne donne pas envie d'y répondre.

  5. #5
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Si comment_id est unique sur toute la table, la requête parait juste.
    Tu es sûr que ce n'est pas un problème avec les données plutôt?

  6. #6
    Membre éprouvé
    Avatar de Gecko
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Décembre 2008
    Messages
    499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Décembre 2008
    Messages : 499
    Points : 1 277
    Points
    1 277
    Par défaut
    J'ai cerné le problème, c'est level qui est pas au point.

    En gros il répète le post jusqu'à atteindre le bon chiffre, voici un petit exemple en image.

    http://www.toine.pro/theme/shiny_hill/etvepocrever.png

    Et du coups beh c'est assez embêtant parce que je vois pas trop comment corriger ça
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($toBe || !$toBe) echo 'That is the question';

    Mes projets: DVP I/O

  7. #7
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    OK. En 2eme lecture je pense que la sous- requête avec le level à 1 n'est pas juste car elle renvoie tous les commentaires de la discussion alors qu'elle devrait renvoyer uniquement ceux qui n'ont pas de parent (colonne comment_parent à NULL ou à 0 suivant ce que tu as choisi)

  8. #8
    Membre éprouvé
    Avatar de Gecko
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Décembre 2008
    Messages
    499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Décembre 2008
    Messages : 499
    Points : 1 277
    Points
    1 277
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    		WITH RECURSIVE children(nid,date,cid,parent,content,uid,level) AS (
    			SELECT nc.news_id,nc.comment_pubdate,nc.comment_id,nc.comment_parent,nc.comment_content,nc.user_id, 0
    			    FROM toine.news_comments nc
    			    WHERE nc.news_id = :news_id
    		    UNION ALL
    			SELECT news_id,comment_pubdate,comment_id,comment_parent,comment_content,user_id, e.level+1
    			    FROM toine.news_comments nc, children e
    			    WHERE nc.comment_parent = e.cid
    		)
    		SELECT * FROM children ORDER BY date, level
    Voici la structure de ma table :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
                                          Table « toine.news_comments » 
         Colonne     |  Type   |                                Modificateurs 
    -----------------+---------+------------------------------------------------------------------------------ 
     comment_id      | integer | non NULL Par défaut, nextval('toine.news_comments_comment_id_seq'::regclass) 
     comment_pubdate | bigint  | 
     comment_plus    | bigint  | non NULL Par défaut, 0 
     comment_minus   | bigint  | non NULL Par défaut, 0 
     comment_content | text    | 
     news_id         | bigint  | 
     user_id         | bigint  | 
     comment_parent  | bigint  | non NULL Par défaut, 0 
    Index : 
        "news_comments_pkey" PRIMARY KEY, btree (comment_id)
    J'ai toujours ce comportement, ou alors j'ai pas compris ce que tu m'as dis, ce qui se peut aussi ^^
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($toBe || !$toBe) echo 'That is the question';

    Mes projets: DVP I/O

  9. #9
    Membre émérite
    Profil pro
    Inscrit en
    Octobre 2008
    Messages
    1 874
    Détails du profil
    Informations personnelles :
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Octobre 2008
    Messages : 1 874
    Points : 2 890
    Points
    2 890
    Par défaut
    Ce que je voulais dire c'est remplacer
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE nc.news_id = :news_id
    par
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    WHERE nc.news_id = :news_id AND comment_parent is null

  10. #10
    Membre éprouvé
    Avatar de Gecko
    Homme Profil pro
    Développeur décisionnel
    Inscrit en
    Décembre 2008
    Messages
    499
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 39
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Développeur décisionnel

    Informations forums :
    Inscription : Décembre 2008
    Messages : 499
    Points : 1 277
    Points
    1 277
    Par défaut
    Merci beaucoup, ça fonctionne et ça m'a bien dégoûté en même temps

    Je ne pensais pas que la solution serait aussi simple.

    Et existe-t-il un moyen de couper la requête de manière propre ?
    Par exemple si j'ai 140 commentaires et que je veux qu'il y en ait 10 par page.
    C'est possible de stopper au dernier enfant précédant la limite si le commentaire suivant a trop d'enfants pour la respecter ?
    Code php : Sélectionner tout - Visualiser dans une fenêtre à part
    if ($toBe || !$toBe) echo 'That is the question';

    Mes projets: DVP I/O

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Construction d'un arbre lexicographique
    Par ColonelHati dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 03/02/2007, 08h40
  2. Réponses: 1
    Dernier message: 02/01/2007, 11h22
  3. [Lisp] Construction d un arbre n-aire
    Par Treuze dans le forum Lisp
    Réponses: 5
    Dernier message: 19/11/2006, 19h22
  4. cherche algorithme de construction d'un arbre
    Par Invité(e) dans le forum Algorithmes et structures de données
    Réponses: 9
    Dernier message: 07/05/2006, 11h04
  5. cherche algorithme de construction d'un arbre
    Par Invité(e) dans le forum Algorithmes et structures de données
    Réponses: 2
    Dernier message: 05/05/2006, 12h28

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