MSSQL 2008 SP нумерация страниц и подсчет общего количества записей - PullRequest
1 голос
/ 08 ноября 2010

В моем SP у меня есть следующее:

with Paging(RowNo, ID, Name, TotalOccurrences) as 
(
    ROW_NUMBER() over (order by TotalOccurrences desc) as RowNo, V.ID, V.Name, R.TotalOccurrences FROM dbo.Videos V INNER JOIN .... 
)
SELECT * FROM Paging WHERE RowNo BETWEEN 1 and 50
SELECT COUNT(*) FROM Paging

В результате я получаю сообщение об ошибке: неверное имя объекта «Пейджинг». Могу ли я запросить снова таблицу пейджинга? Я не хочу включать счетчик для всех результатов в качестве нового столбца ... Я бы предпочел вернуться как другой набор данных Это возможно?

Спасибо, Раду

Ответы [ 4 ]

2 голосов
/ 08 ноября 2010

После дальнейших исследований я нашел другой способ сделать это:

with Paging(RowNo, ID, Name, TotalOccurrences) AS
(
    ROW_NUMBER() over (order by TotalOccurrences desc) as RowNo, V.ID, V.Name,    R.TotalOccurrences FROM dbo.Videos V INNER JOIN .... 
)
select  RowNo, ID, Name, TotalOccurrences, (select COUNT(*) from Paging) as TotalResults  from Paging where RowNo between (@PageNumber - 1 )* @PageSize + 1 and @PageNumber * @PageSize;

Я думаю, что это имеет лучшую производительность, чем вызов дважды запроса.

1 голос
/ 06 августа 2011

Обратите внимание, что план запросов решения Radu D показывает двойные попадания в эти таблицы.Он делает два исполнения под прикрытием.Тем не менее, это все еще может быть лучшим способом, так как я не нашел действительно масштабируемый дизайн 1-запроса.

Менее масштабируемый дизайн 1-запроса - выгрузить заполненный упорядоченный список в @tablevariable, SELECT @@ROWCOUNT, чтобы получить полный счет, и выберите из @tablevariable, где номер строки находится между X и Y. Это хорошо работает для <10000 строк, но с результатами в миллионах строк, заполнение этой @tablevariable становится дорогим.</p>

Гибридный подход заключается в заполнении этой переменной / переменной до 10000 строк.Если не все 10000 строк заполнены, значит, все готово.Если заполнено 10000 строк, вам нужно перезапустить поиск, чтобы получить полный счет.Это хорошо работает, если большинство ваших запросов возвращают менее 10000 строк.Предел 10000 - это грубое приближение, вы можете поиграть с этим порогом для своего случая.

1 голос
/ 08 ноября 2010

Вы не можете сделать это, потому что определяемый вами CTE будет доступен только для ПЕРВОГО запроса, который появляется после его определения. Поэтому, когда вы запускаете запрос COUNT (*), CTE больше не доступен для ссылки. Это просто ограничение CTE.

Таким образом, чтобы выполнить COUNT как отдельный шаг, вам не нужно использовать CTE, а вместо этого использовать полный запрос для COUNT on. Или вы можете заключить CTE во встроенную табличную функцию и использовать ее вместо этого, чтобы сохранить повторение основного запроса, примерно так:

CREATE FUNCTION dbo.ufnExample() 
    RETURNS TABLE
AS
RETURN
(
with Paging(RowNo, ID, Name, TotalOccurrences) as 
(
    ROW_NUMBER() over (order by TotalOccurrences desc) as RowNo, V.ID, V.Name, R.TotalOccurrences FROM dbo.Videos V INNER JOIN .... 
)
SELECT * FROM Paging
)

SELECT * FROM dbo.ufnExample() x WHERE RowNo BETWEEN 1 AND 50
SELECT COUNT(*) FROM dbo.ufnExample() x
0 голосов
/ 08 ноября 2010

Напишите «AS» после имени таблицы CTE Paging, как показано ниже: с Paging AS (RowNo, ID, Name, TotalOccurrence) как
( ROW_NUMBER () более (упорядочено по TotalOccurrence desc) как RowNo, V.ID, V.Name, R.TotalOccurrence FROM dbo.Videos V ) ВЫБРАТЬ * ИЗ ПЕЙДЖИНГА ГДЕ RowNo МЕЖДУ 1 и 50 ВЫБЕРИТЕ СЧЕТЧИК (*) ИЗ СТРАНИЦЫ

...