sql - Order by pairs of values -
i have set of rankings, ordered group , ranking:
group | rank ------------ | 1 | 2 | 3 | 4 | 5 | 6 b | 1 b | 2 b | 3 b | 4 c | 1 c | 2 c | 3 c | 4 c | 5 d | 1 d | 2 d | 3 d | 4
i want interleave groups, ordered group , rank, n rankings per group @ time (here, n=2):
group | rank ------------ | 1 | 2 b | 1 b | 2 c | 1 c | 2 d | 1 d | 2 | 3 | 4 b | 3 b | 4 c | 3 c | 4 d | 3 d | 4 | 5 | 6 c | 5
i have achieved desired result loops , table variables (code pasted here because got non-descript syntax error in sql fiddle):
create table rankings([group] nchar(1), [rank] int) insert rankings values ('a',1), ('a',2), ('a',3), ('a',4), ('a',5), ('a',6), ('b',1), ('b',2), ('b',3), ('b',4), ('c',1), ('c',2), ('c',3), ('c',4), ('c',5), ('d',1), ('d',2), ('d',3), ('d',4) -- input declare @n int = 2 --number of group rankings per rotation -- output declare @orderedrankings table([group] nchar(1), rank int) -- -- in-memory rankings.. deleting used rows declare @rankingstemp table(groupindex int, [group] nchar(1), rank int) insert @rankingstemp select row_number() on (partition rank order [group]) - 1 groupindex, [group], rank rankings order [group], rank -- loop variables declare @maxgroupindex int = (select max(groupindex) @rankingstemp) declare @rankingcount int = (select count(*) @rankingstemp) declare @i int while(@rankingcount > 0) begin set @i = 0; while(@i <= @maxgroupindex) begin insert @orderedrankings ([group], rank) select top(@n) [group], rank @rankingstemp groupindex = @i; t ( select top(@n) * @rankingstemp groupindex = @i ); delete t set @i = @i + 1; end set @rankingcount = (select count(*) @rankingstemp) end select @rankingcount rankingcount, @maxgroupindex maxgroupindex -- view results select * @orderedrankings
how can achieve desired ordering set-based approach (no loops, no table variables)?
i'm using sql server enterprise 2008 r2.
edit: clarify, need no more n
rows per group appear contiguously. goal of query yield ordering, when read sequentially, offers equal representation (n rows @ time) of each group, respect rank.
perhaps this...sql fiddle
order ceiling(rank*1.0/2), group, rank
working fiddle above (column names changed slightly)
updated: burned int math... . should work now. forcing int decimal multiplying 1.0 implicit casting doesn't drop remainder need ceiling round correctly.
Comments
Post a Comment