繁体   English   中英

Postgres的。 如何让所有符合孩子标准的父母?

[英]Postgres. How to get all the parents that meet the childs criteria?

我为寻找此问题的解决方案而有些疯狂:

我得到了这样的表:

表数据

在此处输入图片说明

我想要一个查询来获取所有通过条件的元素以及所有父母,这就是这个结果:

查询结果

在此处输入图片说明

我一直在思考查询:

SELECT a.* FROM table a 
    JOIN table b ON b.id = a.id
    WHERE a.id IN (SELECT DISTINCT c.parent_id FROM table c WHERE c.condition = TRUE)
    OR b.id IN (SELECT DISTINCT c.id FROM table c WHERE c.condition = TRUE); 

但是用这种方法我只能得到一个级别的差异,我的意思是,没有条件,我不能获得超过1个父级。 非常感谢。

您可以为此使用递归CTE

WITH RECURSIVE recCTE AS
(
    /*Get all the true children to seed the recursive query*/
    SELECT
        id,
        parent_id,
        condition as initial_condition,
        1 as depth,
        CAST(id as varchar(50)) as path
    FROM
        table a
    WHERE
        a.id NOT IN (SELECT DISTINCT parent_id from table)
        and a.condition = 'true'

    UNION ALL

    /*Recursive bit that refers back to itself. Find the parents*/
    SELECT
        b.id,
        b.parent_id,
        a.initial_condition,
        depth + 1 as depth,
        cast(path || '>' || b.id as varchar(50)) as path        

    FROM
        recCTE a
        INNER JOIN table b ON
            a.parent_id = b.id
    WHERE
        /*avoid going too deep in case of cycling*/
        depth <= 20
)
SELECT * FROM recCTE

递归CTE使用两个部分:

  1. 递归种子:这是UNION查询的前半部分。 在此,我们确定所有属于“ True”的子代(ID也不是Parent_ID)

  2. 递归术语:这是UNION查询的后半部分。 它在FROM子句中引用自己(recCTE),并再次加入table 将recCTE.parent_id(先前的迭代parent_id)链接到表的id 然后提取该迭代所需的所有信息。

我几乎总是跟踪递归深度(到达此记录需要进行多少次递归)和路径(从最底层的子节点开始,我们曾击中该层次结构的其他节点以到达此记录)。

我使用深度来确保我们不会沿着兔子洞走得太远。 如果您有以下记录:

+----+-----------+
| id | parent_id |
+----+-----------+
|  1 |         5 |
|  5 |         7 |
|  7 |         1 |
+----+-----------+

这将导致无限循环(循环),最坏的情况是它将在深度达到20个循环后停止(1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5> 7> 1> 5)。 还有其他停止循环的方法,例如使用path字段: WHERE a.path NOT LIKE '%' || a.parent_id || '%' WHERE a.path NOT LIKE '%' || a.parent_id || '%' 例如WHERE a.path NOT LIKE '%' || a.parent_id || '%'

如果需要的话,您可以在最终选择中得到更好的选择,但这将为您提供95%的选择。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM