我有以下存储过程,并且只想有一个SQL语句。目前您可以看到有两个语句,一个用于实际的分页,另一个用于需要返回我的应用程序进行分页的总记录数。
但是,由于我从第一个查询中获取总行数,因此下面的效率很低:
COUNT(*) OVER(PARTITION BY 1) as TotalRows
如何将TotalRows设置为输出参数?
ALTER PROCEDURE [dbo].[Nop_LoadAllOptimized]
(
@PageSize int = null,
@PageNumber int = null,
@WarehouseCombinationID int = null,
@CategoryId int = null,
@OrderBy int = null,
@TotalRecords int = null OUTPUT
)
AS
BEGIN
WITH Paging AS (
SELECT rn = (ROW_NUMBER() OVER (
ORDER BY
CASE WHEN @OrderBy = 0 AND @CategoryID IS NOT NULL AND @CategoryID > 0
THEN pcm.DisplayOrder END ASC,
CASE WHEN @OrderBy = 0
THEN p.[Name] END ASC,
CASE WHEN @OrderBy = 5
THEN p.[Name] END ASC,
CASE WHEN @OrderBy = 10
THEN wpv.Price END ASC,
CASE WHEN @OrderBy = 15
THEN wpv.Price END DESC,
CASE WHEN @OrderBy = 20
THEN wpv.Price END DESC,
CASE WHEN @OrderBy = 25
THEN wpv.UnitPrice END ASC
)),COUNT(*) OVER(PARTITION BY 1) as TotalRows, p.*, pcm.DisplayOrder, wpv.Price, wpv.UnitPrice FROM Nop_Product p
INNER JOIN Nop_Product_Category_Mapping pcm ON p.ProductID=pcm.ProductID
INNER JOIN Nop_ProductVariant pv ON p.ProductID = pv.ProductID
INNER JOIN Nop_ProductVariant_Warehouse_Mapping wpv ON pv.ProductVariantID = wpv.ProductVariantID
WHERE pcm.CategoryID = @CategoryId
AND (wpv.Published = 1 AND pv.Published = 1 AND p.Published = 1 AND p.Deleted = 0 AND pv.Deleted = 0 and wpv.Deleted = 0)
AND wpv.WarehouseID IN (select WarehouseID from Nop_WarehouseCombination where UserWarehouseCombinationID = @WarehouseCombinationID)
)
SELECT TOP (@PageSize) * FROM Paging PG
WHERE PG.rn > (@PageNumber * @PageSize) - @PageSize
SELECT @TotalRecords = COUNT(p.ProductId) FROM Nop_Product p
INNER JOIN Nop_Product_Category_Mapping pcm ON p.ProductID=pcm.ProductID
INNER JOIN Nop_ProductVariant pv ON p.ProductID = pv.ProductID
INNER JOIN Nop_ProductVariant_Warehouse_Mapping wpv ON pv.ProductVariantID = wpv.ProductVariantID
WHERE pcm.CategoryID = @CategoryId
AND (wpv.Published = 1 AND pv.Published = 1 AND p.Published = 1 AND p.Deleted = 0 AND pv.Deleted = 0 and wpv.Deleted = 0)
AND wpv.WarehouseID IN (select WarehouseID from Nop_WarehouseCombination where UserWarehouseCombinationID = @WarehouseCombinationID)
END
答案 0 :(得分:1)
我想我在这里理解你的问题。您是否认为计数可以在CTE之前完成 然后作为值传递给CTE作为变量。
,即预先设置@TotalRecords的值,将其传入,然后CTE将使用此计数而不是第二次执行计数?
这是否有意义,或者我在这里错过了你的观点。
答案 1 :(得分:1)
Declare @pagesize as int
Declare @PageNumber as int
Declare @TotalRowsOutputParm as int
SET @pagesize = 3
SET @PageNumber = 2;
--create some test data
DECLARE @SomeData table
(
[ID] [int] IDENTITY(1,1) NOT NULL,
[SomeValue] [nchar](10) NULL
)
INSERT INTO @SomeData VALUES ('TEST1')
INSERT INTO @SomeData VALUES ('TEST2')
INSERT INTO @SomeData VALUES ('TEST3')
INSERT INTO @SomeData VALUES ('TEST4')
INSERT INTO @SomeData VALUES ('TEST5')
INSERT INTO @SomeData VALUES ('TEST6')
INSERT INTO @SomeData VALUES ('TEST7')
INSERT INTO @SomeData VALUES ('TEST8')
INSERT INTO @SomeData VALUES ('TEST9')
INSERT INTO @SomeData VALUES ('TEST10');
--Get total count of all rows
Set @TotalRowsOutputParm = (SELECT COUNT(SomeValue) FROM @SomeData p) ;
WITH Paging AS
(
SELECT rn = (ROW_NUMBER() OVER (ORDER BY SomeValue ASC)),
@TotalRowsOutputParm as TotalRows, p.*
FROM [SomeData] p
)
SELECT TOP (@PageSize) * FROM Paging PG
WHERE PG.rn > (@PageNumber * @PageSize) - @PageSize
PRINT @TotalRowsOutputParm
答案 2 :(得分:0)
如果你想将它分配给变量
,我认为如果不运行两次查询就不能这样做但是,你不能只是添加另一列并做这样的事情吗?
;WITH Paging AS (select *,ROW_NUMBER() OVER(ORDER BY name) AS rn FROM sysobjects)
SELECT (SELECT MAX(rn) FROM Paging) AS TotalRecords,* FROM Paging
WHERE rn < 10
或者在你的情况下
SELECT TOP (@PageSize) *,(SELECT MAX(PG.rn) FROM Paging) AS TotalRecords
FROM Paging PG
WHERE PG.rn > (@PageNumber * @PageSize) - @PageSize
然后从前端抓住那个列
答案 3 :(得分:0)
最后我决定只使用两个不同的SQL语句,一个用于计数,一个用于select。
“COUNT(*)OVER(PARTITION BY 1)作为TotalRows”实际上相当昂贵,而且使用两种不同的语句更快。
感谢所有帮助解决这个问题的人。