在仅选择PageSize需求之前对表中的行进行计数

时间:2018-08-20 15:13:00

标签: sql sql-server tsql

我想先按tblEmployees500k选择行数,然后再获取表@PageNumber中的行总数

ALTER PROCEDURE [dbo].[spPagination] -- ORDER BY EmployeeID
  @PageNumber INT,
  @PageSize   INT
AS
BEGIN
  SET NOCOUNT ON;

    SELECT      Emp.id ,Emp.[firstName], Emp.[lastName], Emp.[salary], Emp.[startDateWork], Emp.age, Count(1) AS [RecordCount] 
    FROM        [dbo].[tblEmployees500k]    Emp
    ORDER BY    id      
    OFFSET      @PageSize * (@PageNumber - 1) ROWS
    FETCH NEXT  @PageSize ROWS ONLY OPTION (RECOMPILE);
END

但是Count(1) AS [RecordCount]导致错误

  

olumn'dbo.tblEmployees500k.id'在选择列表中无效,因为它既不包含在聚合函数中也不在GROUP BY子句中。

4 个答案:

答案 0 :(得分:0)

使用窗口功能:

Count(*) over () AS [RecordCount] 

({count(1)count(*)是等效的。)

答案 1 :(得分:0)

使用聚合函数时,您需要在group by中添加非聚合函数。

您可以尝试使用Count(*) over(partition by Emp.id order by Emp.id)代替count(1)

SELECT      Emp.id ,Emp.[firstName], Emp.[lastName], Emp.[salary], Emp.[startDateWork], Emp.age, Count(*) over(partition by Emp.id order by Emp.id) AS [RecordCount] 
FROM        [dbo].[tblEmployees500k]    Emp       
OFFSET      @PageSize * (@PageNumber - 1) ROWS
FETCH NEXT  @PageSize ROWS ONLY OPTION (RECOMPILE);

编辑

如果要计算表的所有行,则可以尝试使用子查询来获取总计count

SELECT      Emp.id ,Emp.[firstName], Emp.[lastName], Emp.[salary], Emp.[startDateWork], Emp.age, (SELECT COUNT(*) FROM [dbo].[tblEmployees500k]) AS [RecordCount] 
FROM        [dbo].[tblEmployees500k]    Emp       
OFFSET      @PageSize * (@PageNumber - 1) ROWS
FETCH NEXT  @PageSize ROWS ONLY OPTION (RECOMPILE);

或者您可以使用CROSS JOIN来实现。

SELECT      Emp.id ,Emp.[firstName], Emp.[lastName], Emp.[salary], Emp.[startDateWork], Emp.age,t1.cnt AS [RecordCount] 
FROM        
    [dbo].[tblEmployees500k]    Emp 
CROSS JOIN 
    (SELECT COUNT(*) cnt FROM [dbo].[tblEmployees500k]) t1      
OFFSET      @PageSize * (@PageNumber - 1) ROWS
FETCH NEXT  @PageSize ROWS ONLY OPTION (RECOMPILE);

答案 2 :(得分:0)

您也可以使用cross join

 SELECT Emp.id, Emp.[firstName], Emp.[lastName], 
        Emp.[salary], Emp.[startDateWork], Emp.age, cnt.[RecordCount]
 FROM [dbo].[tblEmployees500k] Emp CROSS JOIN
      (SELECT COUNT(*) AS [RecordCount] FROM [dbo].[tblEmployees500k]) cnt;

答案 3 :(得分:0)

只需声明一个变量来存储此信息,并在结果集中使用它,如下所示:

ALTER PROCEDURE [dbo].[spPagination] -- ORDER BY EmployeeID
  @PageNumber INT,
  @PageSize   INT
AS
BEGIN
    SET NOCOUNT ON;

DECLARE @NumOfRows int = (select count(*) from [dbo].[tblEmployees500k] );

SELECT      Emp.id ,Emp.[firstName], Emp.[lastName], Emp.[salary], Emp.[startDateWork], Emp.age, @NumOfRows AS [RecordCount] 
FROM        [dbo].[tblEmployees500k]    Emp
ORDER BY    id      
OFFSET      @PageSize * (@PageNumber - 1) ROWS
FETCH NEXT  @PageSize ROWS ONLY OPTION (RECOMPILE);
END

这样,它将只计算一次。