2011-09-28 36 views
-1

我有类似这样SQL - 从没有多个相同的查找表更新每行的多个字段加入

create table #temp 
(
    log_id int, 
    ...some other fields, 
    one_user_id int, 
    two_user_id int, 
    three_user_id int, 
    four_user_id int, 
    one_username varchar(50), 
    two_username varchar(50), 
    three_username varchar(50), 
    four_username varchar(50) 
) 

我开始了知道所有的用户ID的临时表,但后来我需要仰视他们的用户查找表中的名称并更新临时表中的名称字段。

create table #user_lookup 
(
    user_id int, 
    username varchar(50) 
) 

我知道我可以加入到用户的查找表一次使用不同的别名,让他们所有的每一个ID,但我一直在寻找一个灵活的方式来做到这一点只有一次。

任何想法?

编辑:

好吧,更多信息的目的是为多个用户每行。 #temp表行(并非显示的所有字段)表示一个日志条目,表示多个用户可能进行的多个操作的排序规则,但都绑定到该日志行。

我可能有重复的日志行,每个用户扮演一个角色,但更容易在客户端作为单行使用。

这就是为什么每行有多个用户。

+4

你需要或者'JOIN'多次或修复您的表设计。 – JNK

+0

我说我知道我可以加入多次,我正在寻找替代品 – Ian

+2

@Ian:JNK的观点是没有重新设计你的'#temp'表格结构就没有别的选择。 –

回答

1

我认为这应该工作:

UPDATE temp 
    SET one_username = u1.username 
    , two_username = u2.username 
    , three_username = u3.username 
    , four_username = u4.username 
    FROM #temp as temp 
    join #user_lookup as u1 on u1.user_id = temp.one_user_id 
    join #user_lookup as u2 on u2.user_id = temp.two_user_id 
    join #user_lookup as u3 on u3.user_id = temp.three_user_id 
    join #user_lookup as u4 on u4.user_id = temp.four_user_id 

但我不知道为什么你有四个用户在一个表...;)

+0

这就是我目前正在做的事情。我只是想知道是否有另一种我不熟悉的方式。thx的反馈虽然:) – Ian

+1

对不起,我以为你正在运行四个更新。因此,如果您进行四次连接,则可以进行四次单独更新。我认为四个人更新更好,因为代码更具可读性。 (只有Chuck Norris可以编写可读的SQL) – DavidEG

0

唯一的其他真正的替代解决方案是在拉与IN子句相关的记录并利用CASE语句将用户名与正确的user_id绑定。然而,这比简单地使用JOIN声明更复杂,除了没有涉及多个JOIN之外,并没有真正提供任何优势。下面是一个如何使用这种结构提取数据的完整工作示例:

create table #temp 
(
    one_user_id int, 
    two_user_id int, 
    three_user_id int, 
    four_user_id int, 
    one_username varchar(50), 
    two_username varchar(50), 
    three_username varchar(50), 
    four_username varchar(50) 
) 
insert #temp (one_user_id, two_user_id, three_user_id, four_user_id) values (1, 3, 6, 7) 
insert #temp (one_user_id, two_user_id, three_user_id, four_user_id) values (2, 5, 8, 1) 

;with User_Lookup as (
    select 1 as user_id, 'abc' as username union 
    select 2, 'def' union 
    select 3, 'ghi' union 
    select 4, 'jkl' union 
    select 5, 'mno' union 
    select 6, 'pqr' union 
    select 7, 'stu' union 
    select 8, 'vwx' union 
    select 9, 'jon' union 
    select 10, 'bob' 
), Result as (
    select 
     one_user_id, 
     two_user_id, 
     three_user_id, 
     four_user_id, 
     max(case when U.user_id = one_user_id then U.username end) as one_username, 
     max(case when U.user_id = two_user_id then U.username end) as two_username, 
     max(case when U.user_id = three_user_id then U.username end) as three_username, 
     max(case when U.user_id = four_user_id then U.username end) as four_username 
    from 
     #Temp T, 
     User_Lookup U 
    where 
     U.user_id in (T.one_user_id, T.two_user_id, T.three_user_id, T.four_user_id) 
    group by 
     T.one_user_id, T.two_user_id, T.three_user_id, T.four_user_id 
) 
update 
    #temp 
set 
    one_username = R.one_username, 
    two_username = R.two_username, 
    three_username = R.three_username, 
    four_username = R.four_username 
from 
    Result R 
inner join 
    #temp T on R.one_user_id=T.one_user_id and R.two_user_id=T.two_user_id 
     and R.three_user_id=T.three_user_id and R.four_user_id=T.four_user_id 

select * from #temp 

drop table #temp 

输出:

one_user_id two_user_id three_user_id four_user_id one_username two_username three_username four_username 
1   3   6    7    abc    ghi    pqr    stu 
2   5   8    1    def    mno    vwx    abc