2009-10-05 11 views
0

Je dois réparer les ensembles de chaînes imbriqués cassés via le script ou sql. La table contient une colonne de gauche et une colonne de droite, mais pas de colonne d'identifiant parent. Je suis capable de calculer le niveau de chaque nœud dans l'ensemble imbriqué. Il y a des lacunes dans les valeurs gauche et droite. La structure des niveaux calculés est valide. Est-ce que quelqu'un connaît une solution pour combler les lacunes via SQL? (MySQL)Réparer l'ensemble imbriqué cassé

Aucune des suggestions ne correspond à mon problème, mais merci pour votre engagement.

J'ai travaillé une solution pour moi: 1. première étape de calcul ids parents et transformez à la liste de contiguïté 2. L'utilisation approche de Joe Celko pour convertir des listes de contiguïté à des ensembles imbriqués 3. mettre à jour des valeurs de gauche et de droite

+0

donc, vous voulez pour stocker l'id parent comme dans une liste d'adjacence (\t en plus à gauche/droite)? – VolkerK

Répondre

1

Je voudrais simplement générer une colonne parent_id à partir des valeurs gauche et droite que vous avez, puis régénérer les valeurs gauche et droite.

Si vous ne souhaitez pas modifier votre table actuelle, vous pouvez même le faire dans une table temporaire.

+0

Je suis d'accord - vous êtes assez foutu sans parent_id. Ou du moins c'est ce que j'ai découvert après avoir fait face au même problème. – bisko

+0

J'ai résolu le problème pour calculer le parent_id (sans avoir de colonne parente) en utilisant un SQL suivant: SELECT A.id, IF (B.id IS NULL, 1, B.id) AS parent de la page AS A Page OUFT OUTER JOIN AS B ON B.tree_lft = (SELECT MAX (C.tree_lft) FROM page AS C OERE A.tree_lft> C.tree_lft ET A.tree_lft

+0

Maintenant, je dois régénérer les valeurs gauche et droite. –

1

Chaque ancêtre d'un noeud (c) a une plus petite valeur left et right plus grande. Et le parent immédiat (p) est celui de cet ensemble (d'ancêtres) avec la plus grande valeur left.

E.g.

CREATE TABLE nested (
    id int AUTO_INCREMENT, 
    name varchar(16), 
    parentid int DEFAULT 0, 
    lft int(11), 
    rgt int(11), 
    PRIMARY KEY (id) 
) 

INSERT INTO 
    nested (name, parentid, lft, rgt) 
VALUES 
    ('1'  ,0,1,20), 
    ('1.1' ,0,2,9), 
    ('1.1.1' ,0,3,4), 
    ('1.1.2' ,0,5,6), 
    ('1.1.3' ,0,7,8), 
    ('1.2' ,0,10,19), 
    ('1.2.1' ,0,11,14), 
    ('1.2.1.1',0,12,13), 
    ('1.2.2' ,0,15,16), 
    ('1.2.3' ,0,17,18) 

SELECT 
    p.id as pid, p.name as pname, 
    c.id as cid, c.name as cname 
FROM 
    nested as c 
LEFT JOIN 
    nested as p 
ON 
    p.lft=(
    SELECT 
     MAX(lft) 
    FROM 
     nested AS l 
    WHERE 
     c.lft > l.lft 
     AND c.lft < l.rgt 
) 

retours

pid pname cid cname 
NULL NULL  1  1 
1  1  2  1.1 
2  1.1  3  1.1.1 
2  1.1  4  1.1.2 
2  1.1  5  1.1.3 
1  1  6  1.2 
6  1.2  7  1.2.1 
7  1.2.1 8  1.2.1.1 
6  1.2  9  1.2.2 
6  1.2  10  1.2.3 
0

Il y a 4 ou 5 différents cas de corruption dans un ensemble imbriqué qui sont complètement fixable (si cela est fait dans l'ordre). Snaggle est facile à éviter avec un simple déclenchement des vérifications pour voir si la gauche n'est pas> = la droite. J'ai obtenu les meilleurs résultats en réparant un ensemble imbriqué dans cet ordre. Le SQL lui-même n'est pas difficile une fois que le problème est réparti comme suit.

  • Cross (1: 4 3: 6) ou (1: 2 2: 3)
  • Moins de/Plus (1: 4 1: 3) ou (1: 4 2: 4)
  • Gap (2: 3 5: 6 1: 7) ou (2: 4 5: 6 1: 7)
  • Snaggle (2: 1 4: 2) OR (1: 1)