2011-05-19 17 views
0

我有一個具有整數ID的實體表,我們稱之爲Entities。在另一個表中,我通過爲「From」,「To」以及他們擁有什麼樣的關係(讓我們稱之爲關係表)來建立這些實體之間的單向關係。實體可以通過兩個相應的單向關係而成爲「雙向」,整體事物是圖形或網絡。MySQL中的單向連接和「n度分離」?

我正在尋找一個例程,我可以通過它傳遞一個實體ID以及要分離多少度數,並且它會在傳遞的ID的許多關係中返回每個實體ID。我不知道如何編寫這個例程。這種迭代性質超出了我對存儲過程的經驗。任何線索如何開始這個?

回答

1

對於列的表的關係from_id和to_id

DROP PROCEDURE IF EXISTS find_relationships; 
DELIMITER $$ 

CREATE PROCEDURE find_relationships(start_id int(11), level int(11)) 
BEGIN 
    DECLARE found INT(11) DEFAULT 1; 
    DROP TABLE IF EXISTS related_entities; 
    CREATE TABLE related_entities (id int(11) PRIMARY KEY) ENGINE=HEAP; 
    INSERT INTO related_entities VALUES (start_id); 
    WHILE found > 0 AND level > 0 DO 
    INSERT IGNORE INTO related_entities 
     SELECT DISTINCT from_id FROM relationships r 
     JOIN related_entities rf ON r.to_id = rf.id 
     UNION 
     SELECT DISTINCT to_id FROM relationships r 
     JOIN related_entities rf ON r.from_id = rf.id; 
    SET found = ROW_COUNT(); 
    SET level = level - 1; 
    END WHILE; 
    SELECT * FROM related_entities; 
    DROP TABLE related_entities; 
END; 
$$ 
DELIMITER ; 

如果對任意一個圖的工作,發現給定爲水平距離內的所有連接的節點。

call find_relationships(5, 2); 
+0

我真的很期待嘗試一下。我會在今天下午回覆我的結果。 – 2011-05-19 14:53:21

+0

我不能夠感謝你!它完全按預期工作。 – 2011-05-19 22:50:25

0

在MySQL中沒有with語句,所以你需要一個臨時表。僞代碼:

drop table if exists tmp_nodes; 

create temporary table tmp_nodes as 
select :id as id; 

while :depth++ < :max_depth 
    insert into tmp_nodes 
    select links.id 
    from links 
    join tmp_nodes as nodes on nodes.id = links.parent_id 
    left join tmp_nodes as cycle on cycle.id = links.id 
    where cycle.id is null; 

select id from tmp_nodes optionally where id <> :id; 

貌似piotrm寫道所需功能爲您服務。