【问题标题】:Updating a parent and its children without link between them在没有链接的情况下更新父级及其子级
【发布时间】:2022-06-10 18:10:48
【问题描述】:

我遇到了一个问题,希望您能指导我正确的方向。

一个设施可以有 1..n 个子设施。子设施也可以有 1..n 个子设施。这可能是一种永无止境的关系。

在数据库中,我们只有连接父级和第一个子级的键。

这是一个简短的架构:

--Facility has  : facilityid|parentid
---child1 has   : facilityid|parentid to facility
----child2 has  : facilityid|parentid to child 1 / no key to main parent
-----child2 has : facilityid|parentid to child 2 / no key to main parent

我想要做的是更新一个名为 value 的列,并将其设置为 true 用于父级及其所有子级和子级。现在,由于我只能看到第一个父项及其子项,而看不到子子项,因此我只能更新它们的值。但这让我所有的子孩子都没有更新。

知道子子项和主父项之间没有联系,我将如何做到这一点?

这是一个查询,它为我提供了一个父级及其所有子级。

WITH attributes AS (
    select fa.facilityid, a.id 
    from caip_attribute a
    join caip_facility_attribute fa on a.id = fa.attributeid)

select a.facilityid as parentfacilityid, a.id as parentattributeid, f.id as facilitychildid, fa.attributeid as childattributeid
from attributes a 
join caip_facility f on f.parentid = a.facilityid 
join caip_facility_attribute fa on fa.facilityid = f.id
join caip_attribute at on at.id = fa.attributeid
where at.definitionTypeKey = 'AUTO_CREATE_PROCESS'
order by f.id asc 

此处缺少更新语句,但这是我获取稍后需要更新的值的方式。

谢谢!

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    要更新父级的所有后代,您应该使用递归 CTE。

    假设我们有一个使用自引用外键设置关系的数据表:

    CREATE TABLE t (
        id SERIAL PRIMARY KEY,
        value BOOL DEFAULT FALSE,
        parent_id INT,
        FOREIGN KEY (parent_id) REFERENCES t(id)
    );
    

    首先,返回带有id = 1 的父级及其所有后代的查询将如下所示:

    WITH RECURSIVE children(id, value, parent_id) AS (
        SELECT id, value, parent_id FROM t  WHERE id = 1
        UNION 
            SELECT t.id, t.value, t.parent_id FROM t 
            INNER JOIN children ON children.id = t.parent_id
    )
    SELECT * FROM children
    

    其次,要更新父级的value 及其所有子级,需要在我们的选择查询中为所有带有ids 的行设置value

    UPDATE t SET value = true 
    WHERE id IN (
        WITH RECURSIVE children(id, value, parent_id) AS (
            SELECT id, value, parent_id FROM t  WHERE id = 1
            UNION 
                SELECT t.id, t.value, t.parent_id FROM t 
                INNER JOIN children ON children.id = t.parent_id
        )
        SELECT id FROM children
    )
    

    查看demo

    【讨论】:

      猜你喜欢
      • 2017-09-24
      • 1970-01-01
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-04-19
      • 1970-01-01
      相关资源
      最近更新 更多