2013-07-05 3 views
0

팀 구성원을 그룹으로 구성하는 테이블 집합이 있습니다.재귀 SQL 쿼리 (일반 재귀 유형이 아님)

  • 사용자 (ID의 INT의 PK 등)
  • 팀 (ID의 INT의 PK 등)
  • UsersToTeams (ID의 INT의 PK, 사용자 아이디 INT FK, TeamID INT FK, TeamSupervisor 비트되지 NULL)

사용자가 원하는 수의 팀으로 구성 될 수 있고 팀 수에 관계없이 수퍼바이저를 가질 수 있으므로 테이블에 상위 ID가 없습니다. 사용자는 6 개 팀으로 구성 될 수 있지만 그 중 2 개 팀 만 감독하며 감독 팀 중 하나 또는 둘 다 다른 감독자를 가질 수 있습니다. 따라서 내 계층 구조는 나무보다 웹처럼 보입니다.

는 I 재귀 쿼리가 순환 참조 될 수 있다는 것을 인식한다. 소프트웨어가 그 순간을 처리한다고 가정합니다.

회사의 계층 구조가 사용자의 팀을 감독하는 감독자에 의해 설명되어 있습니다, 그것은하지만 일반적인 방법으로, 계층, 그래서 등 감독의 팀을 감독하는 관리자.

나는 그가 아래로, 무한 레벨을 감독 사용자의 ID를 반환합니다 사용자 ID를 부여, 하나의 질의를 필요로한다. 그런 쿼리는 어떻게 될까요?

Users (ID, Name) 
1 Archie 
2 Betty 
3 Chuck 
4 Dilton 
5 Eddie 
6 Fannie 

사용자 (1)는 관리자 (레벨 3)이다. 사용자 2와 3은 감독자입니다 (2 단계). 사용자 4, 5, 6은 사용자 (1 단계)입니다.

Teams (ID, Name) 
1 Team Alpha 
2 Team Bravo 
3 Sup Team 

UsersToTeams (ID INT PK, UserID INT FK, TeamID INT FK, isSupervisor BIT) 
1 1 3 1 -- Archie supervises Sup Team 
2 2 3 0 -- Betty is a member of Sup Team 
3 3 3 0 -- Chuck is a member of Sup Team 
4 2 1 1 -- Betty supervises team Alpha 
5 4 1 0 -- Dilton is a member of team Alpha 
6 5 1 0 -- Eddie is a member of team Alpha 
7 3 2 1 -- Chuck supervises Team Bravo 
8 6 2 0 -- Fannie is a member of Team Bravo 
  • 아치

    감독자의 팀을 감독하는 관리자입니다.
  • Betty는 사용자 팀을 감독하는 관리자입니다.
  • Chuck은 사용자 팀을 감독하는 관리자입니다.
  • 베티 척은 아치의 팀하지만, 그것을 감독하지 않습니다. 따라서

: 에디가 사람을 감독하지 않기 때문에 내가 아이디 오 (에디)에 전달하면

  1. , 나는 다시 5를 얻어야한다. 패니 척이 감독 팀에 있기 때문에
  2. 내가 아이디 3 (척)에 전달하면, 나는 다시 3, 6 받아야합니다. 나는 사용자 ID 1 (아치)에 전달하면
  3. , 베티와 척 아치의 팀이기 때문에 나는 다시 여기에 설명 된 모든 사용자 ID를 받아야하고, 다른 사람은 베티의 팀 또는 척 팀 중 하나에 있습니다.

미안하지만, 나는 그 SQL 바이올린 링크를 시도했지만, "Building Schema"의 15 분 후에 나는 그것에 대한 희망을 잃었다.

+1

수있는 당신 설치 일부 샘플 데이터를? http://www.sqlfiddle.com/#!6 –

+0

을 사용할 수 있으며 샘플 데이터와 함께 예상 결과 세트 – Surendra

+0

아마도 도움이 될 것입니다. 원하는 작업에 대한 철저한 설명 인 것처럼 보일 수 있습니다. http : //blog.sqlauthority.com/2012/04/24/sql-server-introduction-to-hierarchical-query-using-a-recursive-cte-a-primer/ – OCDan

답변

2

재귀 CTE로이 작업을 수행 할 수 있습니다.

는 먼저, 사용자 자신을 선택하고 반복적으로 그는 즉시 이상 감독있어 모든 사용자 선택 :

declare @userID int = 1; 

with u as (
    select id from users where id = @userID 
    union all 
    select lacky.userID from u supervisor 
    join usersToTeams supervising on supervising.userID = supervisor.id and isSupervisor = 1 
    join usersToTeams lacky on lacky.teamID = supervising.teamID and lacky.isSupervisor = 0 
) 

select * from u 
다음

바이올린의 : http://www.sqlfiddle.com/#!3/525e1/3

+0

예. 그게 전부 야. –

+0

감사합니다. 부수적으로, 이것은 물건을 디자인하는 나쁜 방법처럼 보였다. 완전히 1NF가 아닙니다. 더 나은 레이아웃에 대한 아이디어가 있습니까? – tsilb

+0

@tsilb 죄송합니다, 정상적인 형태에 대해 많이 알지 못합니다. 나는 단지 그것을 작동하게 만든다. = D 당신의 스키마는 나에게 꽤 좋아 보인다. 내가 할 수있는 유일한 변경 사항은 다음 중 하나입니다. 1. UsersToTeams.ID를 제거하고 기본 키를 (UserID, TeamID)로 변경하거나 2. 고유성 제약 조건을 적용하여 사용자가 동일한 팀에 두 번 속하지 않도록하십시오. –