我遇到了一个基本的存储过程,不幸的是我不是一个SQL专家,我想要做的是按2个参数@OrderBy
和@SortOrder
排序提供结果,但是结果仅根据子查询的结果进行排序。
例如:
exec [dbo].[GetTest2] @Page=0,@Limit=150,@OrderBy=N'NetworkName',@SortOrder=N'asc'
它按预期工作,但
exec [dbo].[GetTest2] @Page=0,@Limit=15,@OrderBy=N'NetworkName',@SortOrder=N'asc'
不起作用,因为子查询不返回所有记录。
如何对整个记录集进行排序?
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
答案 0 :(得分:2)
您可以考虑在ROW_NUMBER中添加排序以保持分页一致。我将子查询包装在CTE中,使其更容易阅读。
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
正如评论中所提到的,ROW_NUMBER
可能不是SQL Server更高版本中分页的最佳构造。如果您使用的是至少2012或更高版本,则可以使用OFFSET
和FETCH NEXT
进行分页。然后你的查询变成这样:
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;
答案 1 :(得分:0)
试试这个:
select d.*
from Distributor d, DistributorProducts dp, Product p
where dp.DistributorId = d.id
and p.Id = dp.ProductId
and (p.product = 'Apple' AND p.product = 'Banana');