我有3个表,Client,Tool和ClientTools。 一个客户端可以有多个工具,因此ClientTools充当数据透视表(仅包含Id)。
对于给定的客户,我想要的是拥有完整的工具列表,以及指示客户是否拥有此工具的标志。
我到目前为止的地方是:
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 = 123
和
where (c.Id = 123 or c.Id is null)
但没有效果。
我错过了什么?
提前致谢!
答案 0 :(得分: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
答案 1 :(得分: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
答案 2 :(得分: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
从本质上讲,您说客户端(而不是工具)决定了行是否显示在结果集中。