SQL - 从同一查找表中更新每行的多个字段,而不进行多个连接

时间:2011-09-28 17:09:02

标签: sql-server-2008

我有一个与此类似的临时表

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表行(不是显示的所有字段)表示一个日志条目,表示可能由多个用户组成的多个操作的排序规则,但都绑定到该一个日志行。

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

这就是每行有多个用户的原因。

2 个答案:

答案 0 :(得分: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

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

答案 1 :(得分: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