【问题标题】:Count Persons in tree of Groups with a single query使用单个查询计算组树中的人数
【发布时间】:2021-01-26 08:34:41
【问题描述】:
我正在SQLite 中为Android 编写一个查询,使用这样的架构(这里非常简化,只是我需要的字段)
GROUP
group_id primary_key,
parent_group_id nullable
PERSON
person_id primary_key,
parent_group
我需要计算group 及其后代groups 中persons 的数量,因为我想计算group 的group_id。我想我需要一个 CTE 查询,我整个上午都在阅读它们,但我不明白它们是如何工作的。
【问题讨论】:
标签:
sqlite
android-sqlite
android-room
common-table-expression
【解决方案1】:
您正处于需要 CTE 的正确轨道上。比如:
WITH tree AS
(SELECT g.group_id AS root,
g.group_id AS parent,
p.person_id AS person
FROM "group" AS g
LEFT JOIN person AS p ON g.group_id = p.parent_group
WHERE g.group_id = @desired_group
UNION ALL
SELECT t.root, g.group_id, p.person_id
FROM tree AS t
JOIN "group" AS g ON t.parent = g.parent_group_id
LEFT JOIN person AS p on g.group_id = p.parent_group)
SELECT count(DISTINCT person)
FROM tree;
首先选择所需的组及其成员,然后递归地选择具有给定父组的组的所有成员。最后,计算找到的所有唯一用户。
db<>fiddle example.
【解决方案2】:
我浏览了我能找到的所有文章,并通过大量的试验和错误,我来到了这里(请注意,在我的真实数据库中 person 是 model):
WITH RECURSIVE is_in_group(group_id, group_name, parent_group_id) AS(
SELECT gr.group_id, gr.group_name, gr.parent_group_id FROM _group as gr WHERE gr.group_id = :groupId
UNION ALL
SELECT g.group_id, g.group_name, g.parent_group_id FROM _group as g
JOIN is_in_group as c ON g.parent_group_id = c.group_id
)
SELECT q.group_id, q.group_name, count(m.model_id) as model_count FROM is_in_group as q
LEFT JOIN _model m ON m.parent_group_id = group_id
GROUP BY q.group_id
这将为我提供groups(包括根目录)的列表,每个group 中包含group_id、group_name 和model_count 的models。有了这个,我可以简单地sum 来获取总数,或者查看搜索到的group_id 的行以了解这个group 中有多少model。