2011-11-28 175 views
1

我有一個表,我做一個自連接。我的示例表看起來像這樣優化一個自連接表

-- Table genealogy 
+--------+---------+------+-----+---------+-------+ 
| Field | Type | Null | Key | Default | Extra | 
+--------+---------+------+-----+---------+-------+ 
| parent | int(11) | NO | PRI | NULL |  | 
| child | int(11) | NO | PRI | NULL |  | 
+--------+---------+------+-----+---------+-------+ 
2 rows in set (0.01 sec) 

的概念是這樣的(準備好這一個):

  1. 查找用戶父= 1的孩子,我看的用戶的第一級父= 1。
  2. 要查找用戶父= 1的孫子,我查找是用戶父= 1的孩子的孩子的孩子。
  3. 爲了獲得曾孫(第三級),我尋找孩子是誰的孩子是孩子的父母= 1。
  4. ...等等

它可能會變得有些混亂,但我的查詢工作就好了。我想知道是否有一個更快/最優化的方法做到這一點,因爲我只是在所有的地方重複我的SQL。

-- Get Child 
SELECT parent, child AS '1st Level' FROM genealogy WHERE parent=1; 

-- Get Grandchild 
SELECT a.parent, b.child AS '2nd Level' FROM (SELECT * FROM genealogy WHERE parent=1) a INNER JOIN genealogy b ON a.child=b.parent; 

-- Get Great-Grandchild 
SELECT a.parent, b.child AS '3rd Level' FROM (SELECT a.parent, b.child FROM (SELECT * FROM genealogy WHERE parent=1) a INNER JOIN genealogy b ON a.child=b.parent) a INNER JOIN genealogy b ON a.child=b.parent; 

-- And the list goes on 

回答

1

你可以使用另一種樹狀結構(稱爲嵌套組):

-- Table genealogy 
+--------+---------+------+-----+---------+-------+ 
| Field | Type | Null | Key | Default | Extra | 
+--------+---------+------+-----+---------+-------+ 
| id  | int(11) | NO | PRI | NULL |  | 
| lft | int(11) | NO | NO | NULL |  | 
| rgt | int(11) | NO | NO | NULL |  | 
+--------+---------+------+-----+---------+-------+ 

這將使您選擇的所有孩子的(和大孩子的和盛大,盛大孩子的等等)樹中的節點。

例如選擇家譜ID 1的所有兒童:

SELECT g2.* 
FROM genealogy AS g1, genealogy AS g2 
WHERE 
    (g1.lft BETWEEN g2.lft AND g2.rgt) 
AND 
    (g1.id = 1); 

你可以看看本作的更多信息和更多的例子:http://www.ibase.ru/devinfo/DBMSTrees/sqltrees.html

+0

你有一個樣品SQL我可以看到?這只是激起我的興趣,因爲你的結構與我的不同。 – enchance

+0

這被稱爲嵌套集模型 - 在此搜索會產生大量信息。 –

+0

我添加了一個示例查詢獲取給定節點的所有子節點。嵌套集的確切描述可以在鏈接或wiki上閱讀:http://en.wikipedia.org/wiki/Nested_set_model –