Восстановить сломанный вложенный набор - PullRequest
0 голосов
/ 05 октября 2009

Я должен восстановить поврежденные цепочки вложенных множеств через скрипт или sql. Таблица содержит левый и правый столбец значений, но не содержит родительский идентификатор столбца. Я могу рассчитать уровень каждого узла в рамках вложенного набора. Есть пробелы в левом и правом значениях. Структура вычисленных уровней действительна. Кто-нибудь знает решение, чтобы закрыть пробелы с помощью SQL? (MySQL)

Ни одно из предложений не подходит для моей проблемы, но спасибо за ваше участие.

Я разработал решение для меня: 1. первый шаг - вычисление родительских идентификаторов и преобразование в список смежности. 2. использовать подход Джо Селко для преобразования списков смежности во вложенные множества 3. обновить старые левое и правое значения

Ответы [ 3 ]

1 голос
/ 05 октября 2009

Каждый предок узла (c) имеет меньшее left и большее right значение. И непосредственный родитель (p) - тот из этого набора (из предков) с наибольшим значением left.

* 1006 Е.Г. *

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
  )

возвращает

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
1 голос
/ 05 октября 2009

Я бы просто сгенерировал столбец parent_id из имеющихся у вас левого и правого значений, а затем регенерировал бы левые и правые значения.

если вы не хотите изменять текущую таблицу, вы можете даже сделать это во временной таблице.

0 голосов
/ 11 июля 2013

Существует 4 или 5 различных случаев повреждения в вложенном наборе, которые полностью исправимы (если все сделано в правильном порядке). Проникновение легко предотвратить с помощью простого запуска проверки, чтобы убедиться, что левый не> = правый. Я получил лучшие результаты от ремонта вложенного набора в этом порядке. Сам SQL не сложен, когда проблема разбита следующим образом.

  • Крест (1: 4 3: 6) или (1: 2 2: 3)
  • Под / над (1: 4 1: 3) ИЛИ (1: 4 2: 4)
  • Разрыв (2: 3 5: 6 1: 7) или (2: 4 5: 6 1: 7)
  • Snaggle (2: 1 4: 2) ИЛИ (1: 1)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...