Я пытаюсь получить общее количество строк в таблице 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] вызывает ошибку

столбец 'dbo.tblEmployee 500k.id' недопустим в списке выбора, поскольку он не содержится ни в статистической функции, ни в предложении GROUP BY.

0
E.Meir 20 Авг 2018 в 18:13

4 ответа

Лучший ответ

Когда вы используете агрегатную функцию, вам нужно добавить неагрегированную функцию в 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);
0
D-Shih 20 Авг 2018 в 16:55

Используйте оконную функцию:

Count(*) over () AS [RecordCount] 

(count(1) и count(*) эквивалентны.)

0
Gordon Linoff 20 Авг 2018 в 15:13

Вы также можете использовать 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;
0
Yogesh Sharma 20 Авг 2018 в 15:16

Просто объявите переменную для хранения этой информации и используйте ее в наборе результатов следующим образом:

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

Таким образом, он будет рассчитывать только один раз.

0
Ruslan Tolkachev 21 Авг 2018 в 01:01
51933741