2017-03-23 2 views
0

를 얻을 수 있습니다. 그들은 내 groups 테이블 지금이MySQL의 재귀 쿼리 내가 3 개 테이블이 부모 카테고리

+--------------+--------------+---------------+ 
| id   | user_id  | group_id  | 
+--------------+--------------+---------------+ 
| 1   | 1   | 23   | 
+--------------+--------------+---------------+ 
| 2   | 2   | 24   | 
----------------------------------------------- 

처럼 user_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를 가져옵니다. 내가 원하는 것은 최상위 그룹입니다.

도움 주셔서 감사합니다.

+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 ; 

그런 다음 당신은 당신의 쿼리를 업데이트 할 수 있습니다 일반적으로 단일 쿼리로이 작업을 수행 할 수 있습니다. 당신은 당신의 계급에 얼마나 많은 레벨이있을 수 있는지 미리 아십니까? – Aioros

+0

아니, 레벨은 무제한입니다. 내 마지막 해결책은 PHP로 할 것이지만, 나는 이것이 효과를 얻으려면 좋은 운동이 될 것이라고 생각합니다. –

답변

1

전형적인 솔루션은 PARENT_ID있는 행을 찾을 때까지 혈통을 추적하여 특정 그룹의 최상위 그룹을 반환하는 저장 기능을 만드는 것입니다 = 0

는 그런 다음에 그 기능을 적용 할 수 있습니다 사용자가 속해있는 각 그룹을 선택하고 고유 한 최상위 그룹 세트를 선택하십시오.

이런 식으로 뭔가가 당신을 위해 작동합니다 :

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() 
+0

고마워, 나는 확실히 이것을 나중에 나중에 점검 할 것이다! PHP를 사용하여 보고서를 얻었지만 이것을 테스트 할 것입니다. 감사! –