【问题标题】:Get All Parents/ Children Of Record In Table在表中获取所有记录的父母/孩子
【发布时间】:2020-06-06 13:55:33
【问题描述】:

我有一个名为“Items”的 SQL (Postgres) 表,其架构如下。

id | parent_id | name

parent_id 列是同一个表的 ForeignKey。 (例如项目有父项目,这些项目可以有父项目)

这构成了一个简单的分支层次结构。

目前我查询特定记录并使用for loop 来获取其每个父母/孩子。 这导致执行大量查询。

我想要做的是使用其中一个项目的 id 查询此表,并使用单个查询返回其所有父/子。

我可以通过为孩子使用.select_related(“parent__parent”) 或.prefetch_related(“item_set”) 来完成此操作,但这两种方法都需要事先了解层次结构的深度。

在 Django 中有没有一种方法可以在单个查询中获取所有相关行? 原始 SQL 也很好。

【问题讨论】:

    标签: python sql django


    【解决方案1】:

    这是获取记录的父子层次结构的递归解决方案。

    select * from 
    (WITH RECURSIVE cte_items (id, name, parent_id) AS (
        SELECT id, name, parent_id        
        FROM items
        WHERE id = 1
        UNION ALL
        SELECT e.id, e.name, e.parent_id
        FROM items e
          INNER JOIN cte_items o ON o.id = e.parent_id)
    SELECT id, name, parent_id FROM cte_items) child
    union
    select * from 
    (WITH RECURSIVE cte_items (id, name, parent_id) AS (
        SELECT id, name, parent_id        
        FROM items
        WHERE id = 1
        UNION ALL
        SELECT e.id, e.name, e.parent_id
        FROM items e
          INNER JOIN cte_items o ON o.parent_id = e.id)
    SELECT id, name, parent_id FROM cte_items) parent
    order by parent_id
    

    【讨论】:

    • 这很好,但有没有办法反过来运行它?拿孩子和家长还是记录?
    • 我已经更新了查询,在父子之间使用 UNION。这是你想要的 ?这里更新的查询:sqlfiddle.com/#!5/bf6b9/43
    • 这是一个令人难以置信的查询。太感谢了。生病编辑答案以放置新的 sql
    【解决方案2】:

    操作说明

    我已经用以下内容修改了 Nicola 提供的出色代码。

    代码更清晰一些,在桌子上执行的操作也稍微少了一点。

    每个 SELECTS 中的 where id = 1 是您要查询的记录的实际 ID。

    WITH parents  AS (
        SELECT id, name, parent_id        
        FROM family
        WHERE id = 1 
        UNION ALL
        SELECT e.id, e.name, e.parent_id
        FROM family e
        INNER JOIN parents o ON e.id = o.parent_id)
    , children  as (
        SELECT id, name, parent_id        
        FROM family
        WHERE id = 1  
        UNION ALL
        SELECT e.id, e.name, e.parent_id
        FROM family e
        INNER JOIN children o ON o.id = e.parent_id 
    )
    SELECT id, name, parent_id FROM parents
    UNION
    SELECT id, name, parent_id FROM children;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-02
      • 2018-01-29
      • 2019-09-14
      • 1970-01-01
      • 1970-01-01
      • 2021-12-02
      • 2013-11-23
      • 2018-04-19
      相关资源
      最近更新 更多