Please start any new threads on our new
site at https://forums.sqlteam.com. We've got lots of great SQL Server
experts to answer whatever question you can come up with.
| Author |
Topic |
|
aiken
Aged Yak Warrior
525 Posts |
Posted - 2005-12-29 : 17:13:19
|
I'm struggling with a very slow, inefficient query, and I can't get my head around the right way to do this.I've got a very large table with relationships between users. Easy enough. Now, for a given source user, I want to get a list of the target users and rel_types that apply. That't the part that's driving me mad.create table user_rels(i_users_source int,i_users_target int,rel_type tinyint)insert into user_rels(i_users_source,i_users_target,rel_type)select 100,200,1union allselect 100,200,2union allselect 100,300,1union allselect 100,400,1union allselect 100,500,4 The output I'm looking for (when looking up relationships for source user 100) is:i_users_target,rel_1,rel_2,rel_3,rel_4200,1,1,0,0300,1,0,0,0400,1,0,0,0500,0,0,0,1 Right now, I'm doing something terrible: I'm using a table variable, inserting a list of all target users that the source user has a relationship with, and then (shudders):[code]select i_users,login_name, IsNull((select rel_value from user_rels where rel_type=1 and i_users_source=@iUsers and i_users_target=i_users),0) as rel_1, IsNull((select rel_value from user_rels where rel_type=2 and i_users_source=@iUsers and i_users_target=i_users),0) as rel_2, IsNull((select rel_value from user_rels where rel_type=3 and i_users_source=@iUsers and i_users_target=i_users),0) as rel_3, IsNull((select rel_value from user_rels where rel_type=4 and i_users_source=@iUsers and i_users_target=i_users),0) as rel_4from @tUsersorder by i_users asc ...as you can see, that gets more and more expensive with the addition of each relationship type.There's got to be a better way, and I suspect it involves crosstabs. But I've been mucking with it all morning with no luck. Help!Thanks-b |
|
|
MichaelP
Jedi Yak
2489 Posts |
Posted - 2005-12-29 : 18:18:58
|
How's this?DECLARE @SourceUser INTSELECT @SourceUser = 100create table #user_rels(i_users_source int,i_users_target int,rel_type tinyint)insert into #user_rels(i_users_source,i_users_target,rel_type)select 100,200,1union allselect 100,200,2union allselect 100,300,1union allselect 100,400,1union allselect 100,500,4select u.i_users_target, MAX(CASE u.rel_type WHEN 1 THEN 1 ELSE 0 END) AS rel_1, MAX(CASE u.rel_type WHEN 2 THEN 1 ELSE 0 END) AS rel_2, MAX(CASE u.rel_type WHEN 3 THEN 1 ELSE 0 END) AS rel_3, MAX(CASE u.rel_type WHEN 4 THEN 1 ELSE 0 END) AS rel_4from #user_rels uWHERE u.i_users_source = @SourceUserGROUP BY i_users_targetdrop table #user_rels Michael<Yoda>Use the Search page you must. Find the answer you will. Cursors, path to the Dark Side they are. Avoid them, you must. Use Order By NewID() to get a random record you will.</Yoda> |
 |
|
|
aiken
Aged Yak Warrior
525 Posts |
Posted - 2005-12-29 : 21:19:27
|
| You are my hero. I knew there was a simpler way, but I just couldn't figure how to use aggregates like that.Thanks!-b |
 |
|
|
|
|
|
|
|