问题描述
我正在尝试在两个表之间应用左联接。
这是第一个表:
这是第二张表:
两者都通过WorkTypeId列连接。
现在的要求是,如果表2中有基于某个用户ID的条目,那么我应该从表2中获取该用户ID的所有工作类型ID,而其余工作类型ID应该来自表1,其余列为0或1。
以下是我要应用的查询:
IF EXISTS (SELECT TOP 1 userid FROM Table2 WHERE UserId = @UserId)
BEGIN
Print 'inside If'
Select L.WorkType as WorkTypeName,UW.WorkTypeId,UW.IsChecked,UW.Active,UW.Priority
From Table1 L
Inner Join Table2 UW
On L.WorkTypeId = 1 --UW.WorkTypeId
Where UserId =99 ---@userId
And L.Active = 1
--Order By WorkTypeName ASC
UNION
SELECT L.WorkType as WorkTypeName,0 as IsChecked,1 as Active,0 as Priority
From Table1 L
Left Join Table2 UW
On L.WorkTypeId =1 --UW.WorkTypeId
Where UserId =99 -- @userId
And L.Active = 1
AND UW.Priority IS NULL
END
但是我仍然只看到一行是匹配行,而没有看到左表中的其他行以及硬编码值。
编辑1:
我已将查询更改为以下
Select L.WorkType as WorkTypeName,L.WorkTypeId,UW.Priority
From Table1 L
Inner Join Table2 UW
On L.WorkTypeId = UW.WorkTypeId
Where UserId =99 ---@userId
And L.Active = 1
--Order By WorkTypeName ASC
UNION
SELECT L.WorkType as WorkTypeName,0 as Priority
From Table1 L
Left Join Table2 UW
On UW.WorkTypeId = L.WorkTypeId
AND L.WorkTypeId Not In (Select WorkTypeId From UserWorkType Where UserId =99) --@UserId)
AND L.Active = 1
但是仍然从两个表中获取行
解决方法
这应该通过将过滤条件移至on
子句来实现:
select L.WorkType as WorkTypeName,UW.WorkTypeId,UW.IsChecked,UW.Active,UW.Priority
from Table1 L left join
Table2 UW
on L.WorkTypeId = UW.WorkTypeId and
UW.UserId = 99 ---@userId
where L.Active = 1
,
我认为使用左外部联接应该可以得到结果。 请尝试以下查询:
Select tab2.WorkType as WorkTypeName,tab2.WorkTypeId,tab2.IsChecked,tab2.Active
From Table2 tab2
left Join Table1 tab1 On tab2.WorkTypeId = tab1.WorkTypeId
Where UserId = @userId
And tab2.Active = 1
,
使用内部联接时,On和Where子句之间没有区别。您从两者获得相同的结果。 但是,如果使用左联接,您确实会获得SQL Server中On和Where之间的区别。尝试更改启用位置:
#include <type_traits>
struct S {
int *p;
};
template<typename T>
auto extract(T &&input) {
static_assert(std::is_same_v<std::decay_t<decltype(input)>,S>,"Only struct S is supported");
if constexpr(!std::is_const_v<std::remove_reference_t<decltype(input)>>) {
return input.p;
} else {
return const_cast<const int*>(input.p);
}
}
int main () {
S i;
using t = decltype(extract(i));
static_assert(std::is_same_v<t,int*>);
S const i_c{0};
using t_c = decltype(extract(i_c));
static_assert(std::is_same_v<t_c,const int*>);
return 0;
}
,
有关详细要求,请参阅我的问题。 非常感谢所有的答案。 按照下面的要求,这是我最终创建的查询。
愚蠢的是,我不需要使用其他表(Table2),因为我只需要排他性记录 我正在使用NOT IN。 我保留了注释代码,以保持易懂性。
Select L.WorkType as WorkTypeName,L.WorkTypeId,UW.Priority
From LuWorktypes L
Inner Join UserWorkType UW
On L.WorkTypeId = UW.WorkTypeId
AND UserId =@userId ---@userId
And L.Active = 1
--Order By WorkTypeName ASC
UNION
SELECT L.WorkType as WorkTypeName,0 as IsChecked,1 as Active,0 as Priority
From LuWorktypes L
-- Left Join UserWorkType UW
-- On UW.WorkTypeId = L.WorkTypeId
Where L.WorkTypeId Not In (Select WorkTypeId From UserWorkType Where UserId = @UserId)
AND L.Active = 1