2012-09-06 14 views
2

樹無限深。例如:postgresql計數子女數

+----+-------+--------------------+ 
| id | name | parent_id | value | 
+----+-------+--------------------+ 
| 1 | test1 |   | 0 | 
| 2 | test2 |  1  | 0 | 
| 3 | test3 |  2  | 5 | 
| 4 | test4 |  1  | 0 | 
| 5 | test5 |  4  | 5 | 
| 6 | test6 |  4  | 0 | 
| 7 | test7 |  6  | 10 | 
+----+-------+--------------------+ 

我想獲得一個孩子的總價值。 就像這樣:

+----+-------+--------------------+ 
| id | name | parent_id | value | 
+----+-------+--------------------+ 
| 1 | test1 |   | 20 | = test2.value + test4.value 
| 2 | test2 |  1  | 5 | = test3.value 
| 3 | test3 |  2  | 5 | 
| 4 | test4 |  1  | 15 | = test5.value + test6.value 
| 5 | test5 |  4  | 5 | 
| 6 | test6 |  4  | 10 | = test7.value 
| 7 | test7 |  6  | 10 | 
+----+-------+--------------------+ 

有什麼建議嗎?謝謝!

+0

不知道你需要休息,我不能說什麼明確的關於什麼是正確的模式是,但你的實現是樹木存儲在數據庫中一個非常原始的方法。一些設計模式已經被髮明出來,可以更輕鬆地做各種巧妙的事情,包括你問的問題。例如,查看物化路徑設計模式。請參閱http://www.rampant-books.com/book_0601_sql_coding_styles.htm或其他參考資料。 –

+0

@ hims056:什麼不清楚?遵循'parent_id'鏈接並遞歸求和'count'值。 –

+0

@ hims056第一張桌子是我的,第二張是我想要創建的視圖 – Danfi

回答

11

這裏是希望能解決您的問題遞歸查詢:

WITH RECURSIVE tree (id, parent_id, cnt) AS (
    -- start from bottom-level entries 
    SELECT id, parent_id, 0::bigint AS cnt 
    FROM tbl t 
    WHERE NOT EXISTS (
     SELECT id 
     FROM tbl 
     WHERE parent_id = t.id 
    ) 

    UNION ALL 

    -- join the next level, add the number of children to that of already counted ones 
    SELECT t.id, t.parent_id, tree.cnt + (
      SELECT count(id) 
      FROM tbl 
      WHERE parent_id = t.id 
     ) 
    FROM tbl t JOIN tree ON t.id = tree.parent_id 
) 
SELECT tree.id, max(tree.cnt) AS number_of_children 
FROM tree 
-- use the JOIN if you need additional columns from tbl 
-- JOIN tbl ON tree.id = tbl.id 
-- use the WHERE clause if you want to see root nodes only 
-- WHERE parent_id IS NULL 
GROUP BY tree.id 
ORDER BY tree.id 
; 

我做了一個SQLFiddle了。

+0

謝謝你的回答。我犯了一個錯誤,我真的想得到總價值,但不是數量。抱歉。 – Danfi

+0

最後我用函數來解決它。 – Danfi

+0

恐怕你的實現不正確。請考慮一棵樹有一個有三個孩子的根,兩個首先有兩個孩子,最後一個沒有孩子。根據你的查詢,根有5個孩子(後代),而實際上它有7個。 – lared