I am in trouble with a basical stored procedure, unfortunately I am not a sql expert, what I am trying to do is sort offers result by 2 parameters, @OrderBy
and @SortOrder
, however the result is sorted only on the result of the sub-query. For example:
exec [dbo].[GetTest2] @Page=0,@Limit=150,@OrderBy=N'NetworkName',@SortOrder=N'asc'
it works as expected, but
exec [dbo].[GetTest2] @Page=0,@Limit=15,@OrderBy=N'NetworkName',@SortOrder=N'asc'
doesn't works because the subquery doesn't return all the records.
how can I sort over the entire recordset?
USE [MyContext]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
alter PROCEDURE [dbo].[GetTest2]
@Page int = 0,
@Limit int = 10,
@OrderBy nvarchar(50) = 'OfferId',
@Name nvarchar(100) = NULL,
@SortOrder nvarchar(50) = 'asc'
AS
BEGIN
SET NOCOUNT ON;
SELECT * FROM (SELECT ROW_NUMBER() OVER(ORDER BY @OrderBy) AS ROWNUMBER,
COUNT(*) OVER() AS [Total_Rows],
a.Name AS NetworkName,
o.*
FROM offers AS o
left outer join AffiliateNetworks AS a ON o.NetworkId = a.Id
WHERE (@Name IS NULL OR o.Name LIKE '%' + @Name + '%' )) AS Paged
WHERE
Paged.ROWNUMBER > @Limit * @Page AND
Paged.ROWNUMBER <= (@Limit * @Page) + @Limit
order by
case
when @SortOrder <> 'asc' then NULL
when @OrderBy = 'Name' then Name
end ASC,
case
when @SortOrder <> 'asc' then NULL
when @OrderBy = 'NetworkName' then NetworkName
end ASC,
case
when @SortOrder <> 'desc' then NULL
when @OrderBy = 'Name' then Name
end DESC,
case
when @SortOrder <> 'desc' then NULL
when @OrderBy = 'NetworkName' then NetworkName
end DESC
END
You might consider adding the sorting within the ROW_NUMBER to keep the paging consistent. I wrapped the sub-query in a CTE to make it a little easier to read.
ALTER PROCEDURE [dbo].[GetTest2]
@Page int = 0,
@Limit int = 10,
@OrderBy nvarchar(50) = 'OfferId',
@Name nvarchar(100) = NULL,
@SortOrder nvarchar(50) = 'asc'
AS
BEGIN
SET NOCOUNT ON;
;WITH Paged AS (
SELECT ROW_NUMBER() OVER (
ORDER BY
CASE WHEN @SortOrder = 'ASC'
THEN (CASE @OrderBy WHEN = 'Name' THEN Name WHEN 'NetworkName' THEN a.Name END) END ASC,
CASE WHEN @SortOrder = 'DESC'
THEN (CASE @OrderBy WHEN = 'Name' THEN Name WHEN 'NetworkName' THEN a.Name END) END DESC)
) AS ROWNUMBER,
COUNT(*) OVER() AS [Total_Rows],
a.Name AS NetworkName,
o.*
FROM offers AS o
left outer join AffiliateNetworks AS a ON o.NetworkId = a.Id
WHERE (@Name IS NULL OR o.Name LIKE '%' + @Name + '%' )
)
SELECT *
FROM Paged
WHERE ROWNUMBER - (@Limit * @Page) BETWEEN 1 AND @Limit
ORDER BY ROWNUMBER
END
GO
As mentioned in comments, ROW_NUMBER
may not be best construct for paging in later versions of SQL Server. If you are using at least 2012 or higher, then you can use the OFFSET
and FETCH NEXT
to do your paging. Then your query becomes something like this:
SELECT
COUNT(*) OVER() AS [Total_Rows],
CASE @OrderBy WHEN = 'Name' THEN o.Name WHEN 'NetworkName' THEN a.Name END AS SortName,
a.Name AS NetworkName,
o.*
FROM offers AS o
left outer join AffiliateNetworks AS a ON o.NetworkId = a.Id
WHERE (@Name IS NULL OR o.Name LIKE '%' + @Name + '%' )
ORDER BY
CASE WHEN @SortOrder = 'ASC' THEN SortName ELSE NULL END ASC,
CASE WHEN @SortOrder = 'DESC' THEN SortName ELSE NULL END DESC
OFFSET (@Page * @Limit) ROWS
FETCH NEXT @Limit ROWS ONLY;
Try this:
order by
case
when @OrderBy = 'Name' and @SortOrder = 'asc' then Name
when @OrderBy = 'NetworkName' and @SortOrder = 'asc' then NetworkName
end ASC,
case when @OrderBy = 'Name' and @SortOrder = 'desc' then Name
when @OrderBy = 'NetworkName' and @SortOrder = 'desc' then NetworkName
end DESC
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.