2012-03-07 2 views
0

3 개의 테이블, 클라이언트, 도구 및 ClientTools가 있습니다. 하나의 클라이언트에 여러 도구가있을 수 있으므로 ClientTools는 피벗 테이블 (ID 만 포함)로 작동합니다.3 테이블의 외부 조인

주어진 클라이언트는 도구의 전체 목록과 클라이언트에이 도구가 있는지 여부를 나타내는 플래그를 갖고 싶습니다. 제대로 나에게 모든 도구를 제공합니다 어느

select  t.Id as [ToolId], 
      t.Name as [ToolName], 
      Cast(case when c.Id is NULL then 0 else 1 end as bit) as [HasThisTool], 
from  Tool t 
Left join ClientTools ct 
on   t.Id = ct.ToolId 
Left Join Client c 
on   ct.ClientId = c.Id 

있지만, 모든 클라이언트에 대해 (복수의 클라이언트가이 도구를 소유 할 때 도구 행을 복제) : 지금까지 온

입니다.

그러나 내가 선택한 클라이언트에 가까운 필터를 사용하자마자 내 쿼리는이 클라이언트의 행만 반환하므로 왼쪽 조인이 더 이상 이루어지지 않습니다.

where c.Id = 123where (c.Id = 123 or c.Id is null)을 추가했지만 아무 것도 시도하지 않았습니다.

무엇이 누락 되었습니까?

미리 감사드립니다.

+0

WHERE 절을 게시 할 수 있습니까? –

+0

완료. (오, 최소 글자 수 제한을 환영합니다!) – Shimrod

답변

1

보십시오 : 당신이 당신의 테이블의 순서를 전환하면

select  t.Id as [ToolId], 
      t.Name as [ToolName], 
      Cast(case when ct.Id is NULL then 0 else 1 end as bit) as [HasThisTool] 
from  Tool t 
Left join ClientTools ct 
on   t.Id = ct.ToolId and ct.ClientId = @ClientId 
+0

Mark 고맙습니다! 나는 join 절에서'and'를 사용해야한다는 것을 몰랐습니다. – Shimrod

1

쿼리에서 클라이언트의 이름을 검색하지 않으면 해당 테이블에 가입 할 필요가 없습니다 (실제 문제가 아님). 이 시도 :

select  t.Id as [ToolId], 
      t.Name as [ToolName], 
      Cast(case when ct.Id is NULL then 0 else 1 end as bit) as [HasThisTool] 
from  Tool t 
Left join (SELECT * FROM ClientTools WHERE ClientId = @ClientId) ct 
on   t.Id = ct.ToolId 
+0

이것은 실제 사례의 간단한 샘플입니다. 나는이 where 절을 추가하려고 시도했지만 결과는 ClientId가 지정된 하나의 행을 얻고 있고, 다른 하나는 NULL로 표시되지 않습니다. (예상대로) – Shimrod

+0

@ Shimrod - 내 대답을 수정했습니다. 지금 시도하십시오 – Lamak

+0

감사합니다. Lamak, it 트릭을하는 것처럼 보입니다. 그러나 나는 Mark의 솔루션을 선호합니다. 나는 그것이 당신보다 더 섹시하다는 것을 느낍니다. 여기에 당신을위한 upvote이야! – Shimrod

0

, 그것은 작동합니다 :

본질적으로
select  t.Id as [ToolId], 
      t.Name as [ToolName], 
      Cast(case when t.Id is NULL then 0 else 1 end as bit) as [HasThisTool], 
from  Client c 
Left join ClientTools ct 
on   c.Id = ct.ClientId 
Left Join Tool t 
on   ct.ToolId = t.Id 
where  c.id = 123 

, 해당 클라이언트를 말하고있는 (도구가 아니라)는 행이 결과 집합에 나타나는지 여부를 결정합니다.

+0

반대 방향으로 각 도구를 표시하고 (각 시간) 클라이언트에이 도구가 있으면 행에 표시하십시오. 그러나 당신의 대답에 감사드립니다. – Shimrod