Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

Mover nó na árvore de conjuntos aninhados


Aqui está uma solução que permite mover um nó para qualquer posição na árvore com apenas um único parâmetro de entrada - a nova posição esquerda (newpos) do nó.

Fundamentalmente, existem três conjuntos:
  • Crie um novo espaço para a subárvore.
  • Mova a subárvore para este espaço.
  • Remova o espaço antigo desocupado pela subárvore.

No psuedo-sql, fica assim:
//
 *  -- create new space for subtree
 *  UPDATE tags SET lpos = lpos + :width WHERE lpos >= :newpos
 *  UPDATE tags SET rpos = rpos + :width WHERE rpos >= :newpos
 * 
 *  -- move subtree into new space
 *  UPDATE tags SET lpos = lpos + :distance, rpos = rpos + :distance
 *           WHERE lpos >= :tmppos AND rpos < :tmppos + :width
 * 
 *  -- remove old space vacated by subtree
 *  UPDATE tags SET lpos = lpos - :width WHERE lpos > :oldrpos
 *  UPDATE tags SET rpos = rpos - :width WHERE rpos > :oldrpos
 */

A variável :distance é a distância entre as posições novas e antigas, a :width é o tamanho da subárvore e :tmppos é usado para acompanhar a subárvore que está sendo movida durante as atualizações. Essas variáveis ​​são definidas como:
// calculate position adjustment variables
int width = node.getRpos() - node.getLpos() + 1;
int distance = newpos - node.getLpos();
int tmppos = node.getLpos();
        
// backwards movement must account for new space
if (distance < 0) {
    distance -= width;
    tmppos += width;
}

Para um exemplo de código completo, veja meu blog em

https://rogerkeays.com/how -to-move-a-node-in-nested-sets-with-sql

Se você gosta desta solução, por favor, vote.