parent MySQL -> requête enfant
-
09-09-2019 - |
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.
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.