CTE, ROW_NUMBER и ROWCOUNT

Я пытаюсь вернуть страницу данных, а также количество строк из всех данных в одной хранимой процедуре, которая выглядит следующим образом:

WITH Props AS
(
    SELECT *,
    ROW_NUMBER() OVER (ORDER BY PropertyID) AS RowNumber
    FROM Property
    WHERE PropertyType = @PropertyType AND ...
)   

SELECT * FROM Props 
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 AND (@PageNumber * @PageSize);

Я не могу вернуть число строк (самый высокий номер строки).

Я знаю, что это уже обсуждалось (я видел это: Эффективный способ получения @@rowcount из запроса с использованием row_number), но когда я добавляю COUNT (x) OVER (PARTITION BY 1) в производительности CTE, и запрос выше что обычно не требует времени, которое требуется для выполнения. Я считаю, потому что подсчет рассчитывается для каждой строки? Кажется, я не могу повторно использовать CTE в другом запросе. Table Props имеет 100k записей, CTE возвращает 5k записей.

Ответ 1

В T-SQL это должно быть

;WITH Props AS
(
    SELECT *,
        ROW_NUMBER() OVER (ORDER BY PropertyID) AS RowNumber
    FROM Property
    WHERE PropertyType = @PropertyType AND ...
)

, Props2 AS
(
    SELECT COUNT(*) CNT FROM Props
)

-- Now you can use even Props2.CNT
SELECT * FROM Props, Props2
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 AND (@PageNumber * @PageSize);

теперь у вас есть CNT в каждой строке... Или вы хотели что-то другое? Вам нужен второй набор результатов только с подсчетом? Тогда сделайте это!

-- This could be the second result-set of your query.
SELECT COUNT(*) CNT
FROM Property
WHERE PropertyType = @PropertyType AND ...

Примечание: reedited, запрос 1 Давид ссылался теперь был trashcanned, запрос 2 теперь является запросом 1.

Ответ 2

Вы хотите, чтобы счетчик для всего набора результатов был правильным?

работает ли это быстрее?

SELECT *,(select MAX(RowNumber) from Props) as MaxRow 
FROM Props 
WHERE RowNumber BETWEEN ((@PageNumber - 1) * @PageSize) + 1 
    AND (@PageNumber * @PageSize);