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


milkiway
WRInaute accro
WRInaute accro
 
Messages: 4910
Inscription: 3 Fév 2004

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

Message le Lun Juil 20, 2009 15:41

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
Image
taxonomie_hierarchie
Image

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.


screuscreu
WRInaute impliqué
WRInaute impliqué
 
Messages: 968
Inscription: 14 Jan 2008

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

Message le Lun Juil 20, 2009 16:54

Code: Tout sélectionner
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: Tout sélectionner
$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 ...

jcaron
WRInaute accro
WRInaute accro
 
Messages: 2685
Inscription: 13 Fév 2004

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

Message le Lun Juil 20, 2009 19:27

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: Tout sélectionner
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.


screuscreu
WRInaute impliqué
WRInaute impliqué
 
Messages: 968
Inscription: 14 Jan 2008

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

Message le Lun Juil 20, 2009 21:55

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


milkiway
WRInaute accro
WRInaute accro
 
Messages: 4910
Inscription: 3 Fév 2004

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

Message le Lun Juil 20, 2009 22:14

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.

jcaron
WRInaute accro
WRInaute accro
 
Messages: 2685
Inscription: 13 Fév 2004

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

Message le Lun Juil 20, 2009 22:36

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: Tout sélectionner
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.


screuscreu
WRInaute impliqué
WRInaute impliqué
 
Messages: 968
Inscription: 14 Jan 2008

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

Message le Mar Juil 21, 2009 7:07

milkiway a écrit: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.

Tu peux surement echo la requête de drupal et la copier non ?


milkiway
WRInaute accro
WRInaute accro
 
Messages: 4910
Inscription: 3 Fév 2004

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

Message le Ven Juil 24, 2009 9:13

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: Tout sélectionner
-- 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


screuscreu
WRInaute impliqué
WRInaute impliqué
 
Messages: 968
Inscription: 14 Jan 2008

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

Message le Ven Juil 24, 2009 16:48

Moi pas le temps de regarder avant lundi.
Bon courage


Si vous avez aimé cette discussion, partagez-la sur vos réseaux sociaux préférés :

Lectures recommandées sur ce thème :



Qui est en ligne

Utilisateurs parcourant ce forum: Zecat et 1 invité