假设我有一个MySQL表,它定义了一组东西,每个东西都与1或2个所有者相关联。例如:
CREATE TABLE thing (
id INT UNSIGNED PRIMARY KEY AUTO_INCREMENT
, name CHAR(10)
, first_owner INT UNSIGNED NOT NULL
, second_owner INT UNSIGNED DEFAULT NULL
);
+----+------------+-------------+--------------+
| id | name | first_owner | second_owner |
+----+------------+-------------+--------------+
| 1 | skateboard | Joe | NULL |
| 2 | flashlight | Joe | NULL |
| 3 | drill | Joe | Erica |
| 4 | computer | Erica | NULL |
| 5 | textbook | Diane | NULL |
| 6 | cell phone | Amy | Diane |
| 7 | piano | Paul | Amy |
+----+------------+-------------+--------------+
每个不同的所有者是图的节点,同一行中的两个所有者构成其节点之间的边。从上面的示例行中绘制的图形如下所示:
在这个例子中,有两个组成部分:Joe和Erica是一个组件;黛安,保罗和艾米是另一个。
我想在表格中识别这些组件,因此我添加了另一列:
ALTER TABLE thing ADD COLUMN `group` INT UNSIGNED;
如何编写UPDATE
语句,通过唯一标识该行所属的连接组件来填充此新列?以下是上述示例行的可接受结果的示例:
+----+------------+-------------+--------------+-------+
| id | name | first_owner | second_owner | group |
+----+------------+-------------+--------------+-------+
| 1 | skateboard | Joe | NULL | 1 |
| 2 | flashlight | Joe | NULL | 1 |
| 3 | drill | Joe | Erica | 1 |
| 4 | computer | Erica | NULL | 1 |
| 5 | textbook | Diane | NULL | 2 |
| 6 | cell phone | Amy | Diane | 2 |
| 7 | piano | Paul | Amy | 2 |
+----+------------+-------------+--------------+-------+
我可以使用存储过程执行此操作,但是我的实际场景涉及更多表和数百万行,所以我希望有一种聪明的方法来执行此操作而不用循环游标一周。
这是用于说明问题的简化示例。每个组件应该代表一个“家庭”,大多数只有1或2个节点,但那些节点更多的节点尤为重要。家庭的规模没有一定的严格上限。
答案 0 :(得分:-1)
您可以考虑这种创建hierarchical queries in mysql
的方法CREATE FUNCTION hierarchy_connect_by_parent_eq_prior_id(value INT) RETURNS INT
NOT DETERMINISTIC
READS SQL DATA
BEGIN
DECLARE _id INT;
DECLARE _parent INT;
DECLARE _next INT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET @id = NULL;
SET _parent = @id;
SET _id = -1;
IF @id IS NULL THEN
RETURN NULL;
END IF;
LOOP
SELECT MIN(id)
INTO @id
FROM t_hierarchy
WHERE parent = _parent
AND id > _id;
IF @id IS NOT NULL OR _parent = @start_with THEN
SET @level = @level + 1;
RETURN @id;
END IF;
SET @level := @level - 1;
SELECT id, parent
INTO _id, _parent
FROM t_hierarchy
WHERE id = _parent;
END LOOP;
END
另外,关于这个主题的一篇非常好的文章Adjacency list vs. nested sets: MySQL
答案 1 :(得分:-1)
对相关问题非常好answer
" 将平面表解析为一个最有效/优雅的方法是什么? ?树强>"
有几种方法可以在关系中存储树形结构数据 数据库。您在示例中显示的内容使用两种方法:
- 邻接列表("父"列)和
- 路径枚举(名称列中的虚线数字)。
另一种解决方案叫做嵌套集,它可以存储在 同样的表。阅读" Trees and Hierarchies in SQL for Smarties"通过 Joe Celko提供了有关这些设计的更多信息。
我通常更喜欢名为关闭表的设计(又名"邻接 Relation")用于存储树形结构数据。它需要另一个 表,但是查询树很容易。
请查看原始问题以供参考。