我有一个看起来像这样的查询(我已经更改了表名):
select @user_id
, isnull(ur.rule_value, isnull(manr.rule_value, def.rule_value)) [rule_value]
, isnull(urt.name, isnull(manrt.name, def.name)) [rule_type]
from (select @user_id [user_id]
, rule.rule_value
, rule_type.name
from rule
join rule_type on rule_type.rule_type_id = rule.rule_type_id
where rule.user_id = 1) def
join user on user.user_id = def.user_id
join manager man on man.manager_id = user.manager_id
left join rule ur on ur.user_id = user.user_id
left join rule_type urt on urt.rule_type_id = ur.rule_type_id
left join rule manr on manr.manager_id = man.manager_id
left join rule_type manrt on manrt.rule_type_id = manr.rule_type_id
我期待的是,当用户或用户的经理没有规则时,应使用默认规则。但是,如果用户有规则,我只会得到一个结果。
我已尝试left join
但无效,而def
表的select语句会带回所有默认规则。
我做错了什么?
@user_id
是一个变量。
更新
架构示例
rule
rule_id user_id manager_id rule_value
1 1 1 27
2 1 1 24
3 1 1 25
4 1 1 44
5 1 1 88
1 2 4 2
2 2 4 23
3 2 4 18
3 NULL 4 19
4 NULL 4 20
5 NULL 4 21
rule_type
rule_id name
1 'Craziness'
2 'Number of legs'
3 'Hair ranking'
4 'Banana preference'
5 'Rule 5'
user
user_id manager_id ... other columns
1 1
2 4
3 4
manager
manager_id ... other columns
1
2
3
4
5
6
因此,如果@user_id
为2
,那么我希望输出
2, 2, 'Craziness'
2, 23, 'Number of legs'
2, 18, 'Hair ranking'
2, 20, 'Banana preference'
2, 21, 'Rule 5'
但是如果@user_id是3
那么我会期望输出
3, 27, 'Craziness'
3, 24, 'Number of legs'
3, 19, 'Hair ranking'
3, 20, 'Banana preference'
3, 21, 'Rule 5'
答案 0 :(得分:1)
常规联接实际上是左内联接。你真正想要的是一个外部联接,它获取结果,即使它不能与其他表连接。
答案 1 :(得分:1)
要回答标题中的问题,LEFT JOIN不会像常规JOIN那样行事。 LEFT JOIN与LEFT OUTER JOIN相同,这意味着还将返回LEFT表中与ON标准不匹配的记录。
答案 2 :(得分:1)
摆脱这个:
left join rule ur on ur.user_id = user.user_id
left join rule_type urt on urt.rule_type_id = ur.rule_type_id
left join rule manr on manr.manager_id = man.manager_id
left join rule_type manrt on manrt.rule_type_id = manr.rule_type_id
并将其替换为:
left join rule ur on ur.user_id = user.user_id or ur.user_id = man.manager_id
left join rule_type urt on urt.rule_type_id = ur.rule_type_id
然后将您的开场SELECT更改为:
select @user_id
, isnull(ur.rule_value, def.rule_value) [rule_value]
, isnull(urt.name, def.name) [rule_type]
基本上你做错了的是你有一个实体(user-manager-default),并且你试图通过两个不同的连接将它链接到另一个实体(规则)。如果一个连接不起作用但另一个连接不起作用,则没有返回匹配的NULL以供ISNULL查找。这有点违反直觉。
答案 3 :(得分:1)
我将查询分为两部分。
我认为因为表格结构比原始问题更复杂,这意味着CodeByMoonlight的答案还不够 - 它给了我无法解释的重复行。
我的解决方案如下(关于我在问题中提供的细节):
create table #user_rules
(
user_id int,
rule_value int,
rule_type varchar(255),
rule_type_id,
)
--Insert default values
insert into #user_rules
select @user_id [user_id]
, rule.rule_value
, rule_type.name
, rule_type.rule_type_id
from rule
join rule_type on rule_type.rule_type_id = rule.rule_type_id
where rule.user_id = 1
--Update table with any available values
update #user_rules
set rule_value = ur.rule_value
from user u
join manager m on u.manager_id = m.manager_id
join rule ur on ur.user_id = u.user_id or (ur.manager_id = man.manager_id and ur.user_id is null)
join rule_type urt on urt.rule_type_id = ur.rule_type_id
where urt.rule_type_id = #urse_rules.rule_type_id
and u.user_id = @user_id