MySql Update Row和它的“Descendants”

时间:2014-08-21 23:42:58

标签: mysql sql-update hierarchical-data children

我无法弄清楚如何更新连续的后代/子女。 示例表,名为test

+----+--------+------+
| Id | Parent | Val  |
+----+--------+------+
|  1 |      0 |      |
|  2 |      1 |      |
|  3 |      1 |      |
|  4 |      1 |      |
|  5 |      0 |      |
|  6 |      5 |      |
|  7 |      6 |      |
|  8 |      6 |      |
|  9 |      0 |      |
+----+--------+------+

我想要做的是,当Val设置为某个东西时,更新与该行相关的每一行。例如,如果我跑了

UPDATE test SET Val=1 WHERE Id=5;

我希望Val在Id为6,7和8的行中也为1。

我能想到的最好的事情是

UPDATE test t1 
    JOIN test t2 ON t1.Id = t2.Parent 
    JOIN test t3 ON t2.Id = t3.Parent 
SET t1.Val=1, t2.Val=1, t3.Val=1 WHERE t1.Id=5;

+----+--------+------+
| Id | Parent | Val  |
+----+--------+------+
|  1 |      0 |      |
|  2 |      1 |      |
|  3 |      1 |      |
|  4 |      1 |      |
|  5 |      0 |   1  |
|  6 |      5 |   1  |
|  7 |      6 |   1  |
|  8 |      6 |   1  |
|  9 |      0 |      |
+----+--------+------+

这给了我我想要的东西,但我担心这种做法很差,而且它并没有考虑到变化的深度。我能在这做什么?我认为触发器可能是答案,但这似乎不可能。我收到错误"无法更新存储函数/触发器中的表,因为它已被调用此存储函数/触发器的语句使用"

1 个答案:

答案 0 :(得分:1)

使用MySQL来处理这种情况非常尴尬,因为MySQL doesn't support recursive queries

我通过将层次结构存储为传递闭包而不是" parent_id"来解决这个问题。你正在使用的风格。请参阅我对What is the most efficient/elegant way to parse a flat table into a tree?

的回答

然后你可以更新heirarchy中给定节点的所有后代:

UPDATE test JOIN testclosure AS c ON test.id = c.descendant
SET test.val = 1
WHERE c.ancestor = 5;