I have a stored procedure will be used to page through data. One of the requirements of the procedure is to have a parameter that will be used to sort two columns of data, the sorting should be used when applying the row_number()
.
Some sample data:
CREATE TABLE grp
(
[grp_id] uniqueidentifier primary key,
[grp_nm] varchar(5) not null,
[grp_owner] varchar(200) not null
);
INSERT INTO grp ([grp_id], [grp_nm], [grp_owner])
VALUES
('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 'test1', 'me'),
('1F52A713-EFAC-E211-9C26-78E7D18E1E84', 'test2', 'me'),
('D123B48A-63AB-E211-9C26-78E7D18E1E84', 'test3', 'me'),
('48361F86-2BC2-E211-9C26-78E7D18E1E84', 'test4', 'me'),
('27429A57-93C1-E211-9C26-78E7D18E1E84', 'test5', 'me'),
('D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84', 'test6', 'me'),
('9A07EA21-1AAD-E211-9C26-78E7D18E1E84', 'test7', 'me');
CREATE TABLE mbr
(
[grp_id] uniqueidentifier,
[mbr_id] int not null primary key,
[acct_id] varchar(7) not null,
[cst] varchar(4) null
);
INSERT INTO mbr ([grp_id], [mbr_id], [acct_id], [cst])
VALUES
('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 10, '1', 'AA'),
('7F5F0F16-4EBE-E211-9C26-78E7D18E1E84', 11, '2', 'BB'),
('1F52A713-EFAC-E211-9C26-78E7D18E1E84', 12, '1234578', 'blah'),
('D123B48A-63AB-E211-9C26-78E7D18E1E84', 13, '78', 'test'),
('48361F86-2BC2-E211-9C26-78E7D18E1E84', 14, 'x', 'mbr1'),
('48361F86-2BC2-E211-9C26-78E7D18E1E84', 15, 'a', 'mbr2'),
('27429A57-93C1-E211-9C26-78E7D18E1E84', 16, 'b', 'mbr1'),
('27429A57-93C1-E211-9C26-78E7D18E1E84', 17, 'c', 'mbr2'),
('D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84', 18, 'a', 'mbr1'),
('9A07EA21-1AAD-E211-9C26-78E7D18E1E84', 19, 'a', 'mbr1');
The procedure and the sorting is currently working as written.
But an issue has cropped up with the way that we are applying the row_number()
. The row_number()
should almost simulate the ranking that occurs with dense_rank
but it does not work as expected due to the sorting with the parameter.
For example, if I run the following query:
declare @sort_desc bit = 0
select g.grp_id, g.grp_nm,
m.mbr_id, m.acct_id, m.cst,
row_number() over(order by case when @sort_desc = 0 then g.grp_nm end
, case when @sort_desc = 0 then m.acct_id end
, case when @sort_desc = 1 then g.grp_nm end desc
, case when @sort_desc = 1 then m.acct_id end desc) rn,
dense_rank() over(order by case when @sort_desc = 0 then g.grp_nm end
, case when @sort_desc = 0 then m.acct_id end
, case when @sort_desc = 1 then g.grp_nm end desc
, case when @sort_desc = 1 then m.acct_id end desc) dr
from grp g
inner join mbr m
on g.grp_id = m.grp_id;
See SQL Fiddle with Demo (a trimmed down stored proc is also present)
I get a result of:
| GRP_ID | GRP_NM | MBR_ID | ACCT_ID | CST | RN | DR |
-------------------------------------------------------------------------------------
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 | test1 | 10 | 1 | AA | 1 | 1 |
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 | test1 | 11 | 2 | BB | 2 | 2 |
| 1F52A713-EFAC-E211-9C26-78E7D18E1E84 | test2 | 12 | 1234578 | blah | 3 | 3 |
| D123B48A-63AB-E211-9C26-78E7D18E1E84 | test3 | 13 | 78 | test | 4 | 4 |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 | test4 | 15 | a | mbr2 | 5 | 5 |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 | test4 | 14 | x | mbr1 | 6 | 6 |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 | test5 | 16 | b | mbr1 | 7 | 7 |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 | test5 | 17 | c | mbr2 | 8 | 8 |
| D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84 | test6 | 18 | a | mbr1 | 9 | 9 |
| 9A07EA21-1AAD-E211-9C26-78E7D18E1E84 | test7 | 19 | a | mbr1 | 10 | 10 |
But the desired result is:
| GRP_ID | GRP_NM | MBR_ID | ACCT_ID | CST | RN | expR|
-------------------------------------------------------------------------------------
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 | test1 | 10 | 1 | AA | 1 | 1 |
| 7F5F0F16-4EBE-E211-9C26-78E7D18E1E84 | test1 | 11 | 2 | BB | 2 | 1 |
| 1F52A713-EFAC-E211-9C26-78E7D18E1E84 | test2 | 12 | 1234578 | blah | 3 | 2 |
| D123B48A-63AB-E211-9C26-78E7D18E1E84 | test3 | 13 | 78 | test | 4 | 3 |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 | test4 | 15 | a | mbr2 | 5 | 4 |
| 48361F86-2BC2-E211-9C26-78E7D18E1E84 | test4 | 14 | x | mbr1 | 6 | 4 |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 | test5 | 16 | b | mbr1 | 7 | 5 |
| 27429A57-93C1-E211-9C26-78E7D18E1E84 | test5 | 17 | c | mbr2 | 8 | 5 |
| D5DF9F8E-EDC2-E211-9C26-78E7D18E1E84 | test6 | 18 | a | mbr1 | 9 | 6 |
| 9A07EA21-1AAD-E211-9C26-78E7D18E1E84 | test7 | 19 | a | mbr1 | 10 | 7 |
As you can see the expR
column values are incrementing based on the grp_id
but the rows are still in the correct sort order. I am at a loss of how to get this result and any suggestions would be great.
row_number
is applied to the result.@param IS NULL OR Column = @param
?grp
table has columns with different indicators, let's say the group is restricted to certain users based on the group owner, we are verifying that the proc only is returning the rows that the person has access to...there are several ORs in the where clause but it is not a check between the@param is null
orcolumn = @param
.