【问题标题】:Can't figure out this Postgresql recursive self-join无法弄清楚这个 Postgresql 递归自联接
【发布时间】:2019-12-03 10:38:15
【问题描述】:

大家好,我有下表:

+----+--------------+------------+----------+
| Id |     Name     |    Type    | ParentId |
+----+--------------+------------+----------+
|  1 | Team A       | team       | 2        |
|  2 | Initiative A | initiative | 3        |
|  3 | Initiative B | initiative | 4        |
|  4 | Initiative C | initiative | 5        |
|  5 | Product A    | product    | 6        |
|  6 | Product B    | product    | NULL     |
+----+--------------+------------+----------+

基本上我想做的是递归地自加入相同类型的父级,并且只保留相同类型的最高级别父级。 为了说明我的意思,如果我要对上表执行递归连接,我希望得到以下结果:

+---------+--------+---------------+--------------+------------+-----------+
| Team_Id |  Team  | Initiative_Id |  Initiative  | Product_Id |  Product  |
+---------+--------+---------------+--------------+------------+-----------+
|       1 | Team A |             4 | Initiative C |          6 | Product B |
+---------+--------+---------------+--------------+------------+-----------+

我尝试通过WITH RECURSIVE CTE 进行递归连接,但我不知道如何在最终查询中“汇总”相同类型的父项。

【问题讨论】:

  • 最高级别的主动性是B?
  • 感谢@EdBangga,进行了相应的编辑。很好的收获。
  • " 尝试通过 WITH RECURSIVE CTE 进行递归连接,但我不知道如何在最终查询中“汇总”相同类型的父项。” 也许也发布尝试过的递归 CTE

标签: sql postgresql crosstab recursive-query self-join


【解决方案1】:

以下将为您提供所需的项目列表 - 但您必须将它们转置以获得具有多列的 1 行:

SELECT t1.* FROM table AS t1
LEFT JOIN table AS t2 ON t1.parentId = t2.id
WHERE t1.parentId IS NULL OR t1.type <> t2.type

【讨论】:

    【解决方案2】:

    最好的方法是在 json 中生成这些列,您可以尝试将 json 转换为您的报告。

    但是,您可以使用 json_to_record() 但需要预定义的列类型。

    with cte as (
          SELECT
            '{' || translate( 
                (translate((json_agg
                    (json_build_object(type || 'id', id, type || 'name', name)))::text, '[]', '')),
               '{}', '') || '}' as name          
          FROM table1 
          WHERE id in (
            select max(id) from table1 group by type)
    )
    select x.* FROM cte
    cross join json_to_record(cte.name::json) AS x(teamid text, teamname text, initiativeid text, initiativename text, productid text, productname text);
    

    【讨论】:

      【解决方案3】:

      我想我可能已经用下面的递归 CTE 解决了这个问题。我可以通过此查询的结果看到同一类型的最顶层父级。

      WITH RECURSIVE parent_rollup AS (
        SELECT
              -1,
              -1,
              NULL,
              NULL AS rolled_up_parent_group_uuid,
              NULL AS rolled_up_type
          FROM table t
      
        UNION
      
        SELECT
               t.Id,
               t.ParentId,
               t.type,
               t2.Id,
               t2.Type
          FROM table t
          LEFT JOIN table t1
            ON t.ParentId = t.Id
          JOIN parent_rollup t2
            ON t1.ParentId = t2.Id
      )
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多