代码之家  ›  专栏  ›  技术社区  ›  Matt Ellen Bipin Vayalu

左连接未按预期通过空值

  •  0
  • Matt Ellen Bipin Vayalu  · 技术社区  · 16 年前

    我有一个类似这样的查询(我更改了表名):

    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 表返回所有默认规则。

    我做错了什么?

    @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
    

    所以如果 @用户id 2 然后我会期望输出

    2, 2, 'Craziness'
    2, 23, 'Number of legs'
    2, 18, 'Hair ranking'
    2, 20, 'Banana preference'
    2, 21, 'Rule 5'
    

    3 然后我会期望输出

    3, 27, 'Craziness'
    3, 24, 'Number of legs'
    3, 19, 'Hair ranking'
    3, 20, 'Banana preference'
    3, 21, 'Rule 5'
    
    4 回复  |  直到 16 年前
        1
  •  1
  •   Ikke    16 年前

    常规联接实际上是左内联接。您实际需要的是一个外部联接,它获取结果,即使它不能将其与另一个表联接。

        2
  •  1
  •   tzup    16 年前

        3
  •  1
  •   MartW    16 年前

    摆脱这个:

    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 @user_id
    ,      isnull(ur.rule_value, def.rule_value) [rule_value]
    ,      isnull(urt.name, def.name) [rule_type]
    

        4
  •  1
  •   Matt Ellen Bipin Vayalu    16 年前

    我已将查询分为两部分。

    我认为,因为表结构比我在原始问题中提出的更复杂,这意味着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