2011-06-03 1 views
5

Je souhaite récupérer des données de la table de base de données suivante 'article'. Je veux aller chercher une information d'article dont le category_id est 4. Mais le résultat devrait contenir tous les enregistrements de ses catégories parentes. Par exemple:
'article1' a le parent 'Sub Category1' et son parent est 'Main Category'. Donc, le résultat devrait avoir les lignes 1,2,4 de la table.Quelle sera la requête SQL pour ce problème?

Est-il possible d'écrire une requête SQL pour cela? quelle sera la requête qui peut extraire des données selon la condition ci-dessus?

S'il vous plaît me guider .. !!

merci ..

Répondre

4

S'il vous plaît se référer à cet article: Managing Hierarchical Data in MySQL.

En fait, ils ont le modèle purposed pour obtenir des données hiérarchiques sans récursivité. En ce qu'ils utilisent lft (à gauche) et rgt (à droite) cela à la colonne supplémentaire pour stocker des informations structurelles de la table. lft et rgt sont réglés comme suit

La racine lft est 1. alors son premier enfant lft est le numéro suivant puis son fils dans le prochain numéro jusqu'à ce qu'il n'y ait plus d'enfant alors pour ce noeud (noeud feuille) rgt sera son lft +1 Et nous allons mettre les frères et soeurs lft en tant que rgt +1 et suivre les mêmes règles pour cela aussi.

Et si la numérotation de tous les enfants est faite, elle mettra les parents à rgt +1.

Je n'ai pas l'expliquer, mais d'une manière ordonnée sur le lien avec l'image, il est plus facile à comprendre.

Donc, après cela, vous pouvez facilement explorer la structure imbriquée à l'aide des requêtes suivantes

Pour obtenir l'identifiant de tous les parents pour:

SELECT parent.category_id 
FROM article AS node, 
article AS parent 
WHERE node.lft BETWEEN parent.lft AND parent.rgt 
AND node.category_id = $category_id 
ORDER BY parent.lft; 

Pour SUPPRIMER une ligne:

LOCK TABLE article WRITE; 
SELECT @myLeft := lft, @myRight := rgt, @myWidth := rgt - lft + 1 
    FROM article WHERE category_id = 'row_id'; 
DELETE FROM article WHERE lft BETWEEN @myLeft AND @myRight; 
UPDATE article SET rgt = rgt - @myWidth WHERE rgt > @myRight; 
UPDATE article SET lft = lft - @myWidth WHERE lft > @myRight; 
UNLOCK TABLES; 

Pour insérer un rangée:

LOCK TABLE article WRITE; 
SELECT @myLeft := lft FROM article WHERE category_id = 'parent_id'; 
UPDATE article SET rgt = rgt + 2 WHERE rgt > @myLeft; 
UPDATE article SET lft = lft + 2 WHERE lft > @myLeft; 
INSERT INTO article(title, lft, rgt) VALUES('title', @myLeft + 1, @myLeft + 2); 
UNLOCK TABLES; 

Ceci est quelque peu complexe, mais après la création d'une procédure stockée, il ne sera pas difficile à utiliser.

+0

Merci pour le partage .. Cet article donne requête pour 4 niveau de hierarachy. Ici, le niveau maximum de la hiérarchie peut être inconnu pour différents 'category_id'. – Vin

2

Dans MS SQL 2005/2008:

with cte(category_id, parent_id, title) 
as 
(
    select category_id, parent_id, title 
    from Category 
    where category_id = 4 
    union all 
    select cat.category_id, cat.parent_id, cat.title 
    from Category cat 
     join cte on 
      cat.category_id = cte.parent_id 
) 
select * 
from cte  
1

Ceci est connu dans SQL comme une requête récursive. Oracle et Postgresql utilisent une syntaxe différente de la réponse d'Alex Aza ’, et en MySQL, je ne pense pas que vous pouvez le faire en une seule requête.

WITH RECURSIVE t(category_id, parent_id, title) AS 
(SELECT category_id, parent_id, title 
    from Category 
    where category_id = 4) 
UNION ALL 
SELECT c.category_id, c.parent_id, c.title 
FROM Category c, t WHERE t.parent_id=c.category_id /* ends when parent_id==-1 */ 
) 
SELECT * FROM t; 

Le RECURSIVE est requis.

0

si vous utilisez SQL Server 2008 puis essayez hierarchyid MSDN