Question

Je travaille avec mySQL, et je suis dans une situation où je dois sélectionner les données d'une table qui correspond à un ID à tout niveau parent -.> Hiérarchie des données de l'enfant dans l'autre table

De plus, je voudrais résoudre ce avec une requête SQL bien écrit, plutôt que d'une fonction récursive dans mon code PHP, car cette fonctionnalité sera utilisé un peu.

J'ai essayé la recherche, et je suis tombé sur de nombreux problèmes similaires (la plupart d'entre eux étant résolu), mais aucun d'entre eux m'a aidé.

Pour illustrer la situation, voici ma configuration actuelle

table "articles":

  • article_id
  • category_id
  • ...

catégories de table

  • category_id
  • parent_id
  • ...

Je dois sélectionner tous les articles de « articles » où « articles.category_id » est, disons, 10. Mais reçoivent également tous les articles de toutes les catégories de l'arbre le « categories.category_id » 10 appartient.

Sens, où « 10 » est le parent et tout cela pour les enfants, et vers le haut où 10 est l'enfant et l'ensemble de ses parents.

possible sans fonction php récursive?

Merci.

Était-ce utile?

La solution

Il est possible de faire en MySQL, mais il faut un peu d'effort. Vous devez écrire une fonction comme ceci:

CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
        DECLARE _id INT;
        DECLARE _parent INT;
        DECLARE _next INT;
        DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;

        SET _parent = @id;
        SET _id = -1;

        IF @id IS NULL THEN
                RETURN NULL;
        END IF;

        LOOP
                SELECT  MIN(id)
                INTO    @id
                FROM    categories
                WHERE   parent = _parent
                        AND id > _id;
                IF @id IS NOT NULL OR _parent = @start_with THEN
                        SET @level = @level + 1;
                        RETURN @id;
                END IF;
                SET @level := @level - 1;
                SELECT  id, parent
                INTO    _id, _parent
                FROM    categories
                WHERE   id = _parent;
        END LOOP;
END

et l'utiliser dans une requête:

SELECT  id, parent, level
FROM    (
        SELECT  hierarchy_connect_by_parent_eq_prior_id(id) AS id, @level AS level
        FROM    (
                SELECT  @start_with := 0,
                        @id := @start_with,
                        @level := 0
                ) vars, categories 
        WHERE   @id IS NOT NULL
        ) ho
JOIN    categories hi
ON      hi.id = ho.id

Voir cette entrée dans mon blog pour plus de détails:

Autres conseils

Il est impossible d'aller chercher un arbre entier dans une requête en utilisant la conception de la liste de contiguïté que vous utilisez, étant donné que vous utilisez MySQL.

D'autres marques de soutien base de données extensions SQL pour gérer ce genre de conception. Oracle, Microsoft SQL Server, IBM DB2 et PostgreSQL 8.4 (actuellement en version bêta) en charge les extensions SQL.

D'autres conceptions de base de données existent qui vous permettent d'interroger plus efficacement les arbres. Cette question a été abordée à plusieurs reprises sur StackOverflow, sur les blogs et articles.

Vous pouvez également lire " arbres et dans SQL Hiérarchies Smarties" par Joe Celko, qui va dans plusieurs de ces dessins en profondeur.

Les modèles les plus courants pour stocker des données hiérarchiques dans une base de données relationnelle, est soit adjacent liste ou ce tableau pour une comparaison des avantages et des inconvénients .

Je ne sais pas combien cela cela vous aide, mais je l'ai écrit une petite fonction qui génère un arbre hiérarchique en utilisant une seule requête MySQL. En fait, toute la logique importante est déplacé en PHP. Ma solution utilise le modèle de liste de contiguïté et fait alors l'utilisation de références PHP afin de construire une structure de données d'arbre au moyen d'un plat. Jetez un oeil à l'essentiel ci-dessous et voir si vous obtenez un peu d'inspiration. Je vous aider plus, mais il y a quelques problèmes que je dois traiter à mon travail.

http://gist.github.com/104357

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top