2014-02-07 49 views
1

如果這是一個基本問題,我很抱歉,但我是一個數據庫新手。我正在使用sqlite來管理一些工具的命令行選項列表。一個簡單的版本是:如何設置一個表來在Sqlite中執行遞歸查詢?

 
sqlite> CREATE TABLE option_set (set_id INTEGER, idx INTEGER, value TEXT); 
sqlite> INSERT INTO option_set VALUES(1, 1, 'a'); 
sqlite> INSERT INTO option_set VALUES(1, 2, 'b'); 
sqlite> INSERT INTO option_set VALUES(1, 3, 'c'); 
sqlite> SELECT value FROM option_set WHERE set_id=1 ORDER BY idx; 
a 
b 
c 

這一切工作正常。我想添加一個增強功能,但是,我允許一個option_set包含另一個。例如,如果我將option_set = 2指定爲{'d','e',[option_set = 1],'f'},我希望這意味着選項{'d','e','a' ,'b','c','f'}。問題是如何在數據庫中表達這一點。我沿線的思考的東西:

 
sqlite> CREATE TABLE option_set (set_id INTEGER, idx INTEGER, contained_set_id INTEGER, value TEXT); 
sqlite> INSERT INTO option_set VALUES(1, 1, NULL, 'a'); 
sqlite> INSERT INTO option_set VALUES(1, 2, NULL, 'b'); 
sqlite> INSERT INTO option_set VALUES(1, 3, NULL, 'c'); 
sqlite> INSERT INTO option_set VALUES(2, 1, NULL, 'd'); 
sqlite> INSERT INTO option_set VALUES(2, 2, NULL, 'e'); 
sqlite> INSERT INTO option_set VALUES(2, 3, 1, NULL); 
sqlite> INSERT INTO option_set VALUES(2, 4, NULL, 'f'); 

的想法是,該表的每一行中,我要麼有一個值或其他SET_ID應該擴大。問題是我不知道如何查詢這樣的表 - 我怎麼能產生遞歸選擇的選項列表?我對結構中的內容和價值欄永遠都不是有效的,但不知道如何解決這個問題並不是瘋狂的。不同的餐桌設計會更好嗎?

謝謝。

回答

2

要進行遞歸查詢,你需要一個recursive common table expression

WITH RECURSIVE 
    contained_sets(level, idx, contained_set_id, value) 
    AS (SELECT 0, idx, contained_set_id, value 
     FROM option_set 
     WHERE set_id = 2 
     UNION ALL 
     SELECT level + 1, 
      option_set.idx, 
      option_set.contained_set_id, 
      option_set.value 
     FROM option_set 
     JOIN contained_sets ON option_set.set_id = contained_sets.contained_set_id 
     ORDER BY 1 DESC, 2) 
SELECT value 
FROM contained_sets 
WHERE contained_set_id IS NULL; 

value 
---------- 
d 
e 
a 
b 
c 
f 

(這是支持的SQLite 3.8.3或更高版本)