【问题标题】:postgresql count the number of childrenpostgresql计算孩子的数量
【发布时间】:2012-08-30 21:47:17
【问题描述】:

树的深度是无限的。示例:

+----+-------+--------------------+
| 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  |
+----+-------+--------------------+

有什么建议吗?谢谢!

【问题讨论】:

  • 在不知道您的其余需求的情况下,我无法确定正确的模式是什么,但您的实现是一种在数据库中存储树的非常幼稚的方式。已经发明了一些设计模式,可以更容易地做各种聪明的事情,包括你提出的问题。例如,查看物化路径设计模式。请参阅rampant-books.com/book_0601_sql_coding_styles.htm 或其他参考资料。
  • @hims056:有什么不清楚的地方?按照parent_id 链接并递归求和count 值。
  • @hims056 第一个表是我拥有的,第二个是我想要创建一个视图
  • 我快速谷歌了一下,发现这篇文章几乎就是你的确切用例...ibstaff.net/fmartinez/?p=18

标签: sql postgresql tree count children


【解决方案1】:

参见 F.35.1.5。这里的connectby函数示例:

http://www.postgresql.org/docs/current/static/tablefunc.html

【讨论】:

    【解决方案2】:

    这是一个递归查询,希望能解决您的问题:

    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。

    【讨论】:

    • 感谢您的回答。我犯了一个错误,我真的想得到总值而不是计数。对不起。
    • 恐怕你的实现不正确。请考虑一棵树,它的根有三个孩子,前两个每个有两个孩子,最后一个没有孩子。根据您的查询,根有 5 个孩子(后代),而实际上它有 7 个。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-20
    • 2016-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 2021-01-08
    相关资源
    最近更新 更多