我有 3 张 table :
- 用户
- 用户组
- 群组
一个用户可以属于多个(子)组。它们存储在 user_groups
表中,如下所示
+--------------+--------------+---------------+
| id | user_id | group_id |
+--------------+--------------+---------------+
| 1 | 1 | 23 |
+--------------+--------------+---------------+
| 2 | 2 | 24 |
-----------------------------------------------
现在,在我的 groups
表中,排名靠前的类别是 parent_id = 0
+--------------+--------------+---------------+
| id | parent_id | name |
+--------------+--------------+---------------+
| 1 | 2 | Group 1.1 |
+--------------+--------------+---------------+
| 2 | 0 | Group 1 |
+--------------+--------------+---------------+
| 3 | 2 | Group 1.2 |
+--------------+--------------+---------------+
| 4 | 3 | Group 1.2.1 |
+--------------+--------------+---------------+
| 5 | 2 | Group 1.3 |
+--------------+--------------+---------------+
现在我想构建一个查询,为我提供所有用户的所有父组。我做了一些关于递归查询的研究,我发现了这个特定的帖子: How to create a MySQL hierarchical recursive query
但是我不知道当我加入表格时应该如何处理这个问题。
这是我到目前为止得到的:
SELECT
`users`.`id`,
`users`.`first_name`,
`users`.`last_name`,
`users`.`email`,
`users`.`language`,
`groups`.`name`,
`groups`.`parent_id`
FROM `users`
LEFT JOIN `user_groups`
ON `user_groups`.`user_id` = `users`.`id`
LEFT JOIN `groups`
ON `groups`.`id` = `user_groups`.`group_id`
WHERE
`users`.`created`
BETWEEN
DATE_SUB(NOW(), INTERVAL 365 DAY) AND NOW()
但是这个查询只是获取子组的名称和 ID。我想要的是顶级组。
感谢您的帮助!
最佳答案
典型的解决方案是创建一个存储函数,通过跟踪起源直到找到parent_id = 0 的行,返回任何给定组的顶级组。
然后,您可以将该函数应用于用户所属的每个组,并选择一组不同的顶级组。
这样的东西应该适合你:
delimiter $$
drop function if exists get_top_level_group_id $$
create function get_top_level_group_id (p_group_id int) returns int
begin
declare v_return_val int;
declare v_group_id int;
declare v_parent_id int;
declare continue handler for not found
begin
return -1;
end;
set v_group_id = p_group_id;
set v_parent_id = p_group_id;
while v_parent_id != 0
do
set v_group_id = v_parent_id;
select `parent_id`
into v_parent_id
from `groups`
where id = v_group_id;
end while;
return v_group_id;
end $$
delimiter ;
然后您可以像这样更新查询以获取这些用户及其不同的顶级组:
SELECT DISTINCT
`users`.`id`,
`users`.`first_name`,
`users`.`last_name`,
`users`.`email`,
`users`.`language`,
get_top_level_group_id(`user_groups`.`group_id`) as top_level_group_id
FROM `users`
LEFT JOIN `user_groups`
ON `user_groups`.`user_id` = `users`.`id`
WHERE
`users`.`created`
BETWEEN
DATE_SUB(NOW(), INTERVAL 365 DAY) AND NOW()
关于Mysql递归查询获取父类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42980923/