ebiz-consult PHP Entwicklung
- Ad -
IMPRESSUM dotted_line KONTAKT dotted_line search dotted_line Contact dotted_line sitemap
260 PHP-Resource Mitglieder online


php-resource



Zurück   PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr > Blogs > AmicaNoctis
 

Login

 
eingeloggt bleiben
star Jetzt registrieren   star Passwort vergessen
 

Bewertung: 2 Stimmen mit einer durchschnittlichen Bewertung von 5,00.

[Nested Set] move subtree

"[Nested Set] move subtree" bei Mister Wong speichern "[Nested Set] move subtree" bei YiGG.de speichern "[Nested Set] move subtree" bei Google speichern "[Nested Set] move subtree" bei del.icio.us speichern "[Nested Set] move subtree" bei Digg speichern "[Nested Set] move subtree" bei icio.de speichern "[Nested Set] move subtree" bei My Yahoo speichern
Veröffentlicht: 25-02-2010 um 14:09 von AmicaNoctis
Aktualisiert: 25-02-2010 um 15:22 von AmicaNoctis

Hi there,

there are several multi-statement solutions out there to move a subtree to a new location (possibly inside another parent node), but I couln't find a solution on the Web to achieve this with a single update statement.

Well, here it is:

Code:
-- moves a subtree before the specified position
-- if the position is the rgt of a node, the subtree will be its last child
-- if the position is the lft of a node, the subtree will be inserted before
-- @param l the lft of the subtree to move
-- @param r the rgt of the subtree to move
-- @param p the position to move the subtree before
update tree
set
	lft = lft + if (:p > :r,
		if (:r < lft and lft < :p,
			:l - :r - 1,
			if (:l <= lft and lft < :r,
				:p - :r - 1,
				0
			)
		),
		if (:p <= lft and lft < :l,
			:r - :l + 1,
			if (:l <= lft and lft < :r,
				:p - :l,
				0
			)
		)
	),
	rgt = rgt + if (:p > :r,
		if (:r < rgt and rgt < :p,
			:l - :r - 1,
			if (:l < rgt and rgt <= :r,
				:p - :r - 1,
				0
			)
		),
		if (:p <= rgt and rgt < :l,
			:r - :l + 1,
			if (:l < rgt and rgt <= :r,
				:p - :l,
				0
			)
		)
	)
where :r < :p or :p < :l;
Here's another one which swaps two subtrees:

Code:
-- swaps two subtrees, where A is the subtree having the lower lgt/rgt values
-- and B is the subtree having the higher ones
-- @param al the lft of subtree A
-- @param ar the rgt of subtree A, must be lower than bl
-- @param bl the lft of subtree B, must be higher than ar
-- @param br the rgt of subtree B
update tree
set
	lft = lft + @offset := if (lft > :ar and rgt < :bl,
		:br - :bl - :ar + :al,
		if (lft < :bl, :br - :ar, :al - :bl)
	),
	rgt = rgt + @offset
where lft >= :al and lft <= :br and :ar < :bl;
The drawback of these statements is that lft and rgt values are temporarily ambiguous, so this method can only be applied when there is no unique index on the lft and rgt column.

Please leave a comment if you happen to discover a situation, where this does not work (except when attempting to move a subtree into itself, which would be just stupid and will be ignored intentionally). In spite of numerous tests, I take no responsibility, if this might mess up your Nested Set, so better test with a copy of your table.

Regards,

Amica

Digg this Post! Add Post to del.icio.us Bookmark Post in Technorati Furl this Post!
Kategorie: Sonstiges
Hits 2520 Kommentare 2 Stichworte bearbeiten Hinweis auf diesen Blog-Eintrag per E-Mail verschicken
« Zurück     Startseite des Blogs     Nächste »
Kommentare 2

Kommentare

  1. Alter Kommentar
    permalink
    Veröffentlicht: 25-02-2010 um 15:20 von onemorenerd onemorenerd ist offline
  2. Alter Kommentar
    Benutzerbild von Berni
    Sehr nützlich! Dadurch spart man sich einige SQL-Updates und Nerven.
    permalink
    Veröffentlicht: 25-02-2010 um 15:56 von Berni Berni ist offline
 
Trackbacks 0

Trackbacks


Alle Zeitangaben in WEZ +2. Es ist jetzt 11:35 Uhr.