2010-07-02 101 views
1

我有一個數據庫中的兩個表,一個列表包和一個列出了相關:查找軟件包的依賴

packages 

id | name 
--------- 
0 | xorg 
1 | gnome-session 
2 | gnome-panel 
3 | gnome-mixer-applet 
4 | gnome-media 

depends 

package | depends 
----------------- 
     1 | 0 
     2 | 1 
     3 | 2 
     4 | 2 

很顯然,如果我想找出一個包要看,我可以這樣做:

SELECT * 
    FROM packages 
INNER JOIN depends 
    ON packages.id = depends.package 
WHERE packages.id = @somenumber 

問題是,這隻給了我一個級別的依賴(4取決於2,但它也取決於包1和0)。有沒有辦法在沒有在循環中運行類似的SELECT的情況下獲得所有的依賴關係?我寧願它在SQLite中工作,但如果需要的話,我會使用一個不同的數據庫(只要它在Linux上是免費的和可用的)。

回答

1

PostgreSQL是唯一支持recursive queries的開源RDBMS。例如,你可以運行這個命令:

WITH RECURSIVE package_deps(id) AS (
    SELECT d.package FROM depends d WHERE d.package = @startingnumber 
    UNION ALL 
    SELECT d.package FROM depends d JOIN package_deps pd ON d.depends = pd.id 
) 
SELECT p.* FROM package_deps pd JOIN packages p USING (id); 

SQLite的對遞歸查詢的支持,但也有更簡單的SQL管理分層數據的其他幾種解決方案。請參閱我的演示文稿Models for Hierarchical Data with SQL and PHP

+0

非常有趣。我將不得不嘗試你的演示文稿中的一些模式。 – 2010-07-02 19:06:52

+0

我還在我的新書* SQL Antipatterns *中介紹了樹型數據和許多其他主題:http://www.pragprog.com/titles/bksqla/sql-antipatterns – 2010-07-02 20:03:22