2011-04-11 5 views
2

내가 가지고 다음과 같은 테이블을 조인 조건에 첫 번째 레코드를 선택합니다. 그러나 사용자는 Inactive 일 수 있습니다. 따라서 Delegates 테이블은 프로젝트 데이터에 액세스 할 수있는 사용자를 정의하는 다 대다 (many to many) 테이블입니다.SQL 다중 테이블

내가 필요한 것은 관리자가 Inactive이라고 가정하고 Active 인 프로젝트의 첫 번째 대표를 선택하는 것입니다. OrderNo 필드는 대리인의 순서를 지정합니다 (1이 먼저 있음).

일부 샘플 데이터 :

Project 
1, Project1, 2 
2, Project2, 4 
3, Project3, 1 

Users 
1, Joe, true 
2, John, false 
3, Dave, true 
4, Bob, false 

Delegates 
1, 4, 1 
1, 1, 2 
1, 3, 3 
2, 2, 1 
2, 4, 2 
2, 3, 3 

그래서 내 쿼리의 출력을 보여줄 필요가있다 :

Project1, Joe 
Project2, Dave 
Project3, Joe 

쇼 프로젝트 및 사용자를 ManagerUser_ID이 비활성 인 경우 각 프로젝트에 대해 다음을 선택합니다 User, Delegates, 가장 낮은 숫자가 OrderNo, 즉 Active입니다.

답변

1

(사용 윈도우 함수)

SELECT P.Name, ISNULL(U.Name, FirstDelegate.Name) AS ProjManager 
FROM Projects P LEFT OUTER JOIN 
     Users U ON P.ManagerUser_ID = U.ID AND U.Active = 1 LEFT OUTER JOIN 
     (
      SELECT * FROM 
      (
       SELECT D.ProjectID, 
         US.Name, 
         ROW_NUMBER() OVER (PARTITION BY ProjectID ORDER BY OrderNo) AS SeqNo 
       FROM Delegates D INNER JOIN 
         Users US ON D.UserID = US.ID 
       WHERE US.Active = 1 
      ) AS Del 
      WHERE Del.SeqNo = 1 
     ) AS FirstDelegate ON P.ID = FirstDelegate.ProjectID 
: 당신이 행을 찾을 수 있다면, 분명 당신이 건설하고있는 현재 행은 당신이 원하는 아니다
0
select p.name, 
u.name, 
min(d.orderNo) 
from projects p, 
users u, 
users manager, 
delegates d 
where p.ManagerUser_ID = manager.id 
and manager.active = false 
and p.id = d.projectId 
and d.userid = u.id 
group by p.name, 
u.name 
+0

불행하게도 프로젝트의 첫 번째 Active Delegate를 조사하지 않습니다. 그러면 주문 번호와 함께 프로젝트의 모든 사용자가 나열됩니다. 결과 세트를 활성화 된 가장 낮은 OrderNo로 제한하는 어딘가에 호출이 있어야합니다. – Simon

1

나는 이렇게 될 것이라고 생각합니다. 이전 유효 행을 찾으려면 추가 조인 (왼쪽 조인 사용)을 수행하는 것이 좋습니다.

select p.Name,m.Name from Projects p inner join Users m on p.ManagerUser_ID = m.ID and m.Active = 1 
union all 
select 
    p.Name, 
    u.Name 
from 
    Projects p 
     inner join 
    Delegates d 
     on 
      p.ID = d.ProjectID 
     inner join 
    Users u 
     on 
      d.UserID = u.ID and 
      u.Active = 1 
     left join 
    Delegates d_anti 
     inner join 
    Users u_anti 
     on 
      d_anti.UserID = u_anti.ID and 
      u_anti.Active = 1 
     on 
      p.ID = d_anti.ProjectID and 
      d_anti.OrderNo < d.OrderNo 
where 
    u_anti.ID is null 
이 트릭을 할 것으로 보인다
+0

이것은 정말 가까이에 보이는데, 아픈 사람들은 내일 그것을 확인해야합니다. 그러나 마지막 ON 절은 올바르지 않습니다. - u_anti.OrderNo Simon

+0

@ Simon - 예, 거기에 맞을 것입니다. –

1
Select projectName, userName 
From 

(
    Select projectName, userName, row_number() over (partition by projectName order by priority ASC) as rank 
    From 
    (
     SELECT p.name as projectName, u.name as userName, 1 as priority 
     FROM projects p INNER JOIN users u ON u.active = true and u.id = p.ManagerUser_ID 

     UNION 

     SELECT TOP(1) p.name, u.name, 2 
     FROM Delegates d INNER JOIN projects p ON p.id = d.projectId 
         INNER JOIN users u ON u.id = d.userId 
     Where u.active = true 
     Order by u.OrderNo ASC 
    ) 
) 
where rank = 1