Besoin d'aide pour une requête MySQL jointe + affichage (hiérarchisation de données)

Discussion dans 'Développement d'un site Web ou d'une appli mobile' créé par milkiway, 20 Juillet 2009.

  1. milkiway
    milkiway WRInaute accro
    Inscrit:
    3 Février 2004
    Messages:
    4 196
    J'aime reçus:
    0
    Bonjour,

    Je suis en train de développer un site web mais mes connaissances en MySQL me font bloquer sur ce que pas mal d'entre vous doivent considérer comme une broutille.
    M'apporteriez-vous un peu d'aide ?

    J'ai deux tables dans ma base MySQL.

    Je souhaiterais afficher, à partir des données suivantes :
    taxonomie_data
    [​IMG]
    taxonomie_hierarchie
    [​IMG]

    La liste qui suit :
    Entrées
    • Salades
    • Feuilletés
    • Légumes
    • Fromage
    Plats
    • Viande
    • Volaille

    En sachant que dans la table taxonomie_hierarchie, 'parent' est l'équivalence du tid de la table taxonomie_data (afin de pouvoir recouper les données).

    Quelle requête effectuer ?
    Comment l'afficher en regroupant les termes relatifs aux "Entrées" et ceux relatifs aux "Plats" ?

    Je suis paumé, j'ai repris cette structure de la taxonomie de Drupal qui est très très bien faite.

    Merci à vous !

    Mais je suis totalement infoutu d'y arriver.
     
  2. screuscreu
    screuscreu WRInaute impliqué
    Inscrit:
    14 Janvier 2008
    Messages:
    687
    J'aime reçus:
    0
    Code:
    SELECT
        Data.nom
        Data2.nom
    FROM
        taxo_data as Data,
        taxo_data as Data2,
        taxo_hier as Hier
    WHERE 
        Data.tid = Hier.tid AND
        Hier.parent <> 0    AND
        Hier.parent = Data2.tid
    ORDER BY
        Hier.parent ASC, Data.poids ASC
    et dans ton PHP tu affiche ton Data2.nom que si il est différent de celui d'avant :
    Code:
    $oldNom = ''
    foreach($mesResultats as $thisResult):
        if($oldNom != $thisResult->Data2->nom):
            $oldNom = $thisResult->Data2->nom;
            echo $oldNom
        endif
        echo $thisResult->Data->nom
    endforeach
    

    A toi de remplacer par ta syntaxe.
    A essayer (je ne promet rien)... Bonne chance !

    Au pire, envoi un export des 2 tables en sql pour que l'on puisse tester en "vrai"

    EDIT : il y a surement bcp plus optimisé je pense ...
     
  3. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 579
    J'aime reçus:
    0
    Evidemment ça ne marchera que sur deux niveaux (sinon il faut multiplier le nombre de références à taxo_data et taxo_hier).

    Une autre option consiste à faire une requête pour chaque "niveau", et d'utiliser une procédure récursive (qui s'appelle elle-même).

    Genre:
    Code:
    function affiche_niveau($niveau)
    {
      ... requete SQL genre select * from taxo_data td,taxo_hier as th where td.tid=th.tid and th.parent=$niveau
      boucle sur résultats
      {
        ... afficher résultat ...
        affiche_niveau($resultat->tid);
      }
    }
    
    Evidemment ça fait plus de requêtes SQL, ce qui n'est pas forcément idéal, mais un petit cache peut aider.

    Jacques.
     
  4. screuscreu
    screuscreu WRInaute impliqué
    Inscrit:
    14 Janvier 2008
    Messages:
    687
    J'aime reçus:
    0
    J'ai jamais osé faire de la récursivité en PHP ... et je me demande à l'instant pourquoi ...
    bonne idée Jacques !

    Bon courage et tiens nous au courant
     
  5. milkiway
    milkiway WRInaute accro
    Inscrit:
    3 Février 2004
    Messages:
    4 196
    J'aime reçus:
    0
    Merci je regarde tout ça demain, par contre Drupal core arrive à faire le résultat en UNE requête.
    Je pense que tout se joue au niveau du tri de l'array des résultats en PHP.
    C'est surement moins gourmand en ressources.
     
  6. jcaron
    jcaron WRInaute accro
    Inscrit:
    13 Février 2004
    Messages:
    2 579
    J'aime reçus:
    0
    Ben plusieurs options:
    - tu limites à 2 niveaux, et la requête donnée plus tôt fait effectivement tout ça en une seule requête
    - tu fais une série de union avec 1 niveau, 2 niveaux, 3 niveaux, etc.
    - tu fais une seule requête avec juste une jointure entre les deux tables, et le traitement se fait au niveau php pour reconstruire l'"arbre" et l'afficher. Pas top difficile ceci dit. Je ne m'aventurerai pas à l'écrire en php parce que je n'ai pas l'habitude mais en perl par exemple ça donnerait quelque chose du genre (pas testé):

    Code:
    sub display_tree
    {
      my $children = shift;
      my $node = shift;
    
      print "<UL>";
      print "<LI>$node->{name}</LI>";
      display_tree($children,$_) for @{$children->{$node->{tid}};
      print "</UL>";
    }
    
    sub read_tree
    {
      my $dbh = shift;
    
      my $nodes = $dbh->selectall_arrayref("SELECT * FROM taxo_data td,taxo_hier th WHERE td.tid=td.tid");
      my $children;
      for my $node (@$nodes)
      {
        push @{$children->{$node->{parent}}}, $node;
      }
      display_tree($children,$children->{0});
    }
    
    Je pense que ça montre bien qu'un peu de récursivité ça aide. Sinon on peut y arriver en gérant une pile, mais ça revient au même.

    Il y a peut-être aussi une option avec un group_concat qui permet de déplacer la préparation de la liste des enfants dans la bdd.

    Bref, there's more than one way to do it :)

    Jacques.
     
  7. screuscreu
    screuscreu WRInaute impliqué
    Inscrit:
    14 Janvier 2008
    Messages:
    687
    J'aime reçus:
    0
    Tu peux surement echo la requête de drupal et la copier non ?
     
  8. milkiway
    milkiway WRInaute accro
    Inscrit:
    3 Février 2004
    Messages:
    4 196
    J'aime reçus:
    0
    Bon et bien j'ai beau tout essayer je n'y arrive pas :(
    Voici la table (j'ai regroupé les deux tables puisqu'il n'y avait pas d'intérêt d'en avoir deux) :
    Code:
    -- phpMyAdmin SQL Dump
    -- version 3.1.3.1
    -- http://www.phpmyadmin.net
    --
    -- Serveur: localhost
    -- Généré le : Ven 24 Juillet 2009 à 10:11
    -- Version du serveur: 5.1.33
    -- Version de PHP: 5.2.9-2
    
    SET SQL_MODE="NO_AUTO_VALUE_ON_ZERO";
    
    --
    -- Base de données: `site`
    --
    
    -- --------------------------------------------------------
    
    --
    -- Structure de la table `taxonomie_data`
    --
    
    CREATE TABLE IF NOT EXISTS `taxonomie_data` (
      `tid` tinyint(4) NOT NULL AUTO_INCREMENT,
      `vid` tinyint(4) NOT NULL,
      `hid` tinyint(4) NOT NULL,
      `nom` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
      `description` text COLLATE utf8_unicode_ci NOT NULL,
      `poids` tinyint(4) NOT NULL,
      PRIMARY KEY (`tid`)
    ) ENGINE=MyISAM  DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci AUTO_INCREMENT=9 ;
    
    --
    -- Contenu de la table `taxonomie_data`
    --
    
    INSERT INTO `taxonomie_data` (`tid`, `vid`, `hid`, `nom`, `description`, `poids`) VALUES
    (1, 1, 0, 'Entrées', 'Recettes d''entrées.', 1),
    (2, 1, 0, 'Plats', 'Recettes de plats.', 2),
    (3, 1, 1, 'Salades', 'Recettes de salade.', 1),
    (4, 1, 1, 'Feuilletés', '', 2),
    (5, 1, 1, 'Légumes', '', 3),
    (6, 1, 2, 'Fromage', '', 4),
    (7, 1, 2, 'Viande', '', 1),
    (8, 1, 2, 'Volaille', '', 2);
    Mon but étant d'avoir un résultat du type :
    -Entrées
    --Salades
    --Feuilletés
    --Légumes
    -Plats
    --Fromage
    --Viande
    --Volaille

    Je sais que c'est tout bête, mais je vous assure, après avoir passé plus d'une heure, je n'arrive à rien, pire, je sature le serveur avec des boucles infinies !

    Je pense qu'il doit y avoir un moyen d'y arriver facilement et surtout sans consommer trop de ressources, en tout cas c'est le but.

    A vot' bon coeur et un grand merci d'avance.

    tid = id du terme
    vid = id du vocabulaire, ici 1 à chaque fois
    hid = indication de hiérarchie
    poids = juste pour classer
     
  9. screuscreu
    screuscreu WRInaute impliqué
    Inscrit:
    14 Janvier 2008
    Messages:
    687
    J'aime reçus:
    0
    Moi pas le temps de regarder avant lundi.
    Bon courage
     
Chargement...
Similar Threads - Besoin aide requête Forum Date
Besoin d'aide pour requête SQL PHP Développement d'un site Web ou d'une appli mobile 12 Novembre 2016
Requête MySQL besoin d'aide Développement d'un site Web ou d'une appli mobile 15 Septembre 2011
[PHP/MYSQL] Besoin d'aide pour la simplification d'une requete Développement d'un site Web ou d'une appli mobile 9 Juillet 2009
Besoin d'aide sur requête svp. Développement d'un site Web ou d'une appli mobile 21 Novembre 2008
Requête sql : besoin d'aide Développement d'un site Web ou d'une appli mobile 19 Juillet 2008
Besoin d'aide pour requête SQL Développement d'un site Web ou d'une appli mobile 30 Octobre 2007
Besoin d'aide pour une requête sql Développement d'un site Web ou d'une appli mobile 14 Juin 2007
Besoin d'aide : intégration lien d'une requete mysql Développement d'un site Web ou d'une appli mobile 6 Mai 2007
Besoin d'aide pour une requete sql Administration d'un site Web 23 Mars 2007
Résolu : Besoin d'aide sur une requete MySQL Développement d'un site Web ou d'une appli mobile 11 Février 2007
PHP->Besoin d'aide pour une requête Développement d'un site Web ou d'une appli mobile 3 Janvier 2007
Besoin aide pour afficher légende sur requête MSQL!! Développement d'un site Web ou d'une appli mobile 3 Juillet 2006
[PHP/MYSQL] Besoin d'aide dans une requête Administration d'un site Web 17 Juin 2005
Pose de liens : Besoin d'aide d'ordre technique et besoin d'éclairage Netlinking, backlinks, liens et redirections 9 Mars 2022
Besoin d'aide pour le lancement de mon Application Demandes d'avis et de conseils sur vos sites 12 Août 2021
Besoin d'aide pour la compréhension d'une application Développement d'un site Web ou d'une appli mobile 1 Août 2021
Besoin d'aide SEO pour mon site Débuter en référencement 13 Mai 2021
Besoin d'aide pour soucis avec le certbot chez OVH - VPS URL Rewriting et .htaccess 6 Avril 2021
Récapitulatif Besoin d'avis et d'aide pour mon site web. Débuter en référencement 1 Novembre 2020
Besoin d'aide pour comprendre mon Analyse Dareboost Débuter en référencement 24 Août 2019