【发布时间】:2014-09-11 06:41:52
【问题描述】:
我已经建立了一个网络/树,现在,从一个节点开始,我试图选择位于这个节点和另一个节点之间的所有节点——全部在一个查询中。
假设有两张表,一张用于存储具有属性的对象,另一张用于存储它们的(直接)关系。让我们保持示例简单。
CREATE TABLE objects (id varchar(64) PRIMARY KEY);
INSERT INTO objects VALUES ('seat'), ('chair'), ('furniture'), ('barstool'), ('stool');
CREATE TABLE parentships ( parent varchar(64) NOT NULL, child varchar(64) NOT NULL, PRIMARY KEY (parent, child), CONSTRAINT fk_child FOREIGN KEY (child) REFERENCES objects (id), CONSTRAINT fk_parent FOREIGN KEY (parent) REFERENCES objects (id) );
INSERT INTO parentships VALUES ('furniture', 'seat'), ('seat', 'chair'), ('seat', 'stool'), ('stool', 'barstool');
家具是根/端节点。让我试着想象一下这个小网络/树。
furniture --- seat -+- chair
|
+- stool --- barstool
我假设我需要使用SUBSELECT、LOOP 和过程创建递归,但我以前从未使用过LOOP 或自制过程。也许你可以帮我解释一下,而我会继续自己搜索/尝试。
{magic query (parameter 'barstool')}
+-----------+
| parent |
+-----------+ <--- This is what I want.
| stool |
| chair |
| seat |
| furniture |
+-----------+
我已经找到了一种手动执行前两步迭代的方法。
SET @p = '';
SET @p = ( SELECT parent FROM parentships WHERE child IN ('barstool', @p) );
SELECT parent FROM parentships WHERE child IN ('barstool', @p);
但是循环的文档让我很困惑。这是我的尝试,但我收到了错误消息:
CREATE PROCEDURE find_all_ancestors(node varchar)
BEGIN
SET @p = '';
label1: LOOP
SET @p = ( SELECT parent FROM parentships WHERE child IN (node, @p) );
IF @p != 'furniture' THEN
ITERATE label1
END IF
LEAVE label1
END LOOP label1
SET @x = @p
END
但是我收到了几条错误消息,从这个开始:
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'label1: LOOP
SET @p = ( SELECT parent FROM parentships WHERE child ' at line 4
另外,无论如何,我都需要将迭代的@p 添加到中间结果数组中,而 MySQL 不允许使用数组。所以也许我完全使用了错误的方法。
干杯。
【问题讨论】:
标签: mysql loops recursion subquery