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 |
sql_er
Constraint Violating Yak Guru
267 Posts |
Posted - 2007-10-10 : 17:53:47
|
Guys,I have a table A with 2 columns, both VARCHAR(255). The same word in the first column can be mapped to multiple different words in the 2nd column of table A. What I would like in the output are only TOP 3 such words from column 2 for each DISTINCT word in column one. TOP is defined by the alphabetic order. Below are the input and desired output examples:Input tablesss bsss dsss csss bsss edef rdef sxyz nxyz txyz lDesired outputsss asss bsss cdef rdef sxyz lxyz nxyz tI know how to solve it using the WHILE loop, in a long way, but was wondering if someone can suggest an efficient SET BASED approach (i.e. a query) to achieve that.Thanks a lot! |
|
tkizer
Almighty SQL Goddess
38200 Posts |
Posted - 2007-10-10 : 18:17:55
|
[code]DECLARE @t table (c1 char(3), c2 char(1))INSERT INTO @t (c1, c2)SELECT 'sss', 'b' UNION ALLSELECT 'sss', 'd' UNION ALLSELECT 'sss', 'c' UNION ALLSELECT 'sss', 'b' UNION ALLSELECT 'sss', 'e' UNION ALLSELECT 'def', 'r' UNION ALLSELECT 'def', 's' UNION ALLSELECT 'xyz', 'n' UNION ALLSELECT 'xyz', 't' UNION ALLSELECT 'xyz', 'l'SELECT c1, c2FROM @t t1WHERE (SELECT COUNT(DISTINCT c2) FROM @t WHERE c1 = t1.c1 AND c2 >= t1.c2) <= 3ORDER BY c1, c2[/code]Tara KizerMicrosoft MVP for Windows Server System - SQL Serverhttp://weblogs.sqlteam.com/tarad/ |
 |
|
johnsql
Posting Yak Master
161 Posts |
Posted - 2007-10-11 : 10:53:23
|
quote: Originally posted by sql_er Guys,I have a table A with 2 columns, both VARCHAR(255). The same word in the first column can be mapped to multiple different words in the 2nd column of table A. What I would like in the output are only TOP 3 such words from column 2 for each DISTINCT word in column one. TOP is defined by the alphabetic order. Below are the input and desired output examples:Input tablesss bsss dsss csss bsss edef rdef sxyz nxyz txyz lDesired outputsss asss bsss cdef rdef sxyz lxyz nxyz tI know how to solve it using the WHILE loop, in a long way, but was wondering if someone can suggest an efficient SET BASED approach (i.e. a query) to achieve that.Thanks a lot!
Alternative solutiondeclare @t table(longWord varchar(50), letter varchar(50))insert @tselect 'sss', 'b'union all select 'sss', 'd'union all select 'sss', 'c'union all select 'sss', 'e'union all select 'sss', 'a'union all select 'def', 'r'union all select 'def', 's'union all select 'xyz', 'n'union all select 'xyz', 't'union all select 'xyz', 'l'union all select 'xyz', 'w'select longWord, letter FROM @t t1WHERE t1.letter in( select top 3 letter from @t WHERE longWord=t1.longWord order by longWord, letter) order by longword,letter |
 |
|
sql_er
Constraint Violating Yak Guru
267 Posts |
Posted - 2007-10-11 : 11:42:39
|
Thanks a lot folks!The solutions were great! |
 |
|
Lamprey
Master Smack Fu Yak Hacker
4614 Posts |
Posted - 2007-10-11 : 15:23:31
|
Here is another less efficient way to do it. :)SELECT a.c1, a.c2FROM @t aINNER JOIN @t b ON a.c1 = b.c1WHERE a.c2 >= b.c2GROUP BY a.c1, a.c2 HAVING COUNT(DISTINCT b.c2) BETWEEN 1 AND 3ORDER BY 1 ASC |
 |
|
sql_er
Constraint Violating Yak Guru
267 Posts |
Posted - 2007-10-15 : 13:45:56
|
This one works well as well.Thanks! |
 |
|
|
|
|
|
|