I have the following stored procedure which returns A
, B
, and the count in descending order. I am trying to use ROW_NUMBER
, so I can page the records, but I want the first row number 1
to be the record with the highest count, so basically, if I return a table with 3 records and the count is 30
, 20
, 10
, then row number 1
should correspond with count 30
, row number 2
should correspond with count 20
, and row number 3
should correspond with count 10
. dbo.f_GetCount
is a function that returns a count.
create procedure dbo.Test
as
@A nvarchar(300) = NULL,
@B nvarchar(10) = NULL
as
select @A = nullif(@A,'')
,@B = nullif(@B,'');
select h.A
,hrl.B
,dbo.f_GetCount(hrl.A,h.B) as cnt
from dbo.hrl
inner join dbo.h
on h.C = hrl.C
where(@A is null
or h.A like '%'+@A+'%'
)
and (@B is null
or hrl.B = @B
)
group by hrl.B
,h.A
order by cnt desc;
In applications, the ROW NUMBER() method is used for pagination. You can, for example, present a list of customers by page, with 10 rows each page. The given code statement shows the use of ROW_NUMBER function to return employee rows from 1 to 5.
Row number is the most common ranking function used in SQL Server. The ROW_NUMBER() function generates a sequential number for each row within a partition in the resultant output. In each partition, the first-row number begins with 1.
The Row_Number function is used to provide consecutive numbering of the rows in the result by the order selected in the OVER clause for each partition specified in the OVER clause. It will assign the value 1 for the first row and increase the number of the subsequent rows.
If you'd like to number each row in a result set, SQL provides the ROW_NUMBER() function. This function is used in a SELECT clause with other columns. After the ROW_NUMBER() clause, we call the OVER() function. If you pass in any arguments to OVER , the numbering of rows will not be sorted according to any column.
WITH q AS
(
SELECT h.A, hrl.B,
dbo.f_GetCount(hrl.A,h.B) as cnt
FROM dbo.hrl
INNER JOIN dbo.h on h.C = hrl.C
WHERE (@A IS NULL OR h.A like '%' + @A + '%')
AND (@B IS NULL OR hrl.B = @B)
GROUP BY hrl.B, h.A
)
SELECT q.*, ROW_NUMBER() OVER (ORDER BY cnt DESC) AS rn
FROM q
ORDER BY rn DESC
To retrieve first 10
rows, use:
WITH q AS
(
SELECT h.A, hrl.B,
dbo.f_GetCount(hrl.A,h.B) as cnt
FROM dbo.hrl
INNER JOIN dbo.h on h.C = hrl.C
WHERE (@A IS NULL OR h.A like '%' + @A + '%')
AND (@B IS NULL OR hrl.B = @B)
GROUP BY hrl.B, h.A
)
SELECT TOP 10 q.*,
ROW_NUMBER() OVER (ORDER BY cnt DESC, A, B) AS rn
FROM q
ORDER BY cnt DESC, A, B
To retrieve rows between 11
and 20
, use:
SELECT *
FROM (
WITH q AS
(
SELECT h.A, hrl.B,
dbo.f_GetCount(hrl.A,h.B) as cnt
FROM dbo.hrl
INNER JOIN dbo.h on h.C = hrl.C
WHERE (@A IS NULL OR h.A like '%' + @A + '%')
AND (@B IS NULL OR hrl.B = @B)
GROUP BY hrl.B, h.A
)
SELECT q.*,
ROW_NUMBER() OVER (ORDER BY cnt DESC, A, B) AS rn
FROM q
) qq
WHERE rn BETWEEN 11 AND 20
ORDER BY cnt DESC, A, B
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With