[英]Get All Parents/ Children Of Record In Table
I have an SQL (Postgres) table named “Items” with the following schema.我有一个名为“Items”的 SQL (Postgres) 表,其架构如下。
id | parent_id | name
Where the parent_id
column is a ForeignKey to the same table.其中
parent_id
列是同一个表的外键。 (Eg items have parent items and those items can have parent items) (例如项目有父项目,这些项目可以有父项目)
This makes a simple branching hierarchy.这构成了一个简单的分支层次结构。
Currently I query for the specific record and use a for loop
to get each of its parents/ children.目前我查询特定记录并使用
for loop
来获取它的每个父/子。 This results in numerous queries being executed.这导致执行大量查询。
What I'm wanting to do is query this table using the id of one of the items and get all of its parents/ children returned using a single query.我想要做的是使用其中一项的 id 查询此表,并使用单个查询返回其所有父/子。
I can accomplish this by using .select_related(“parent__parent”)
or .prefetch_related(“item_set”)
for the children, but both of these approaches would require knowing the depth of the hierarchy before hand.我可以通过为孩子使用
.select_related(“parent__parent”)
或.prefetch_related(“item_set”)
来实现这一点,但这两种方法都需要事先了解层次结构的深度。
Is there a way in Django to get all of the related rows in a single query? Django 中有没有办法在单个查询中获取所有相关行? Raw SQL is fine too.
原始 SQL 也很好。
This is a recursive solution for getting the parent and children hierarchy of a record.这是用于获取记录的父级和子级层次结构的递归解决方案。
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
OP Note操作说明
I have modified the great code provided by Nicola with the following.我用以下内容修改了 Nicola 提供的很棒的代码。
The code is a little clearer and performs marginally fewer actions on the table.代码更清晰一些,并且在表上执行的操作略少。
The where id = 1
in each of the SELECTS is the actual id of the record you are wanting to query for.每个 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;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.