Пейджинг результатов SQL Server 2005
-
08-06-2019 - |
Вопрос
Как просмотреть результаты в SQL Server 2005?
Я пробовал это в SQL Server 2000, но надежного способа сделать это не было.Теперь мне интересно, есть ли в SQL Server 2005 какой-либо встроенный метод?
Под разбиением на страницы я подразумеваю, например, что если я перечисляю пользователей по их имени, я хочу иметь возможность возвращать только первые 10 записей, затем следующие 10 записей и так далее.
Любая помощь приветствуется.
Решение
Вы можете использовать the Row_Number()
функция.Его используют следующим образом:
SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
Из чего он выдаст набор результатов с RowID
поле, которое вы можете использовать для перехода между ними.
SELECT *
FROM
( SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
) As RowResults
WHERE RowID Between 5 AND 10
и т. д.
Другие советы
Если вы пытаетесь получить это одним оператором (общая сумма плюс подкачка).Возможно, вам потребуется изучить поддержку SQL Server для предложения Partition by (оконные функции в терминах ANSI SQL).В Oracle синтаксис аналогичен приведенному выше примеру с использованием row_number(), но я также добавил предложениеsection by, чтобы получить общее количество строк, включенных в каждую строку, возвращаемую при разбиении на страницы (общее количество строк равно 1262):
SELECT rn, total_rows, x.OWNER, x.object_name, x.object_type
FROM (SELECT COUNT (*) OVER (PARTITION BY owner) AS TOTAL_ROWS,
ROW_NUMBER () OVER (ORDER BY 1) AS rn, uo.*
FROM all_objects uo
WHERE owner = 'CSEIS') x
WHERE rn BETWEEN 6 AND 10
Обратите внимание, что у меня есть где владелец = 'CSEIS' и мой раздел принадлежит владельцу.Итак, результаты:
RN TOTAL_ROWS OWNER OBJECT_NAME OBJECT_TYPE
6 1262 CSEIS CG$BDS_MODIFICATION_TYPES TRIGGER
7 1262 CSEIS CG$AUS_MODIFICATION_TYPES TRIGGER
8 1262 CSEIS CG$BDR_MODIFICATION_TYPES TRIGGER
9 1262 CSEIS CG$ADS_MODIFICATION_TYPES TRIGGER
10 1262 CSEIS CG$BIS_LANGUAGES TRIGGER
Принятый ответ на этот вопрос на самом деле мне не подходит... Мне пришлось преодолеть еще один барьер, чтобы заставить его работать.
Когда я попробовал ответить
SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
WHERE RowID Between 0 AND 9
он потерпел неудачу, жалуясь, что не знает, что такое RowID.
Мне пришлось обернуть его во внутренний выбор следующим образом:
SELECT *
FROM
(SELECT
Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
) innerSelect
WHERE RowID Between 0 AND 9
и тогда это сработало.
Когда мне нужно выполнить разбиение по страницам, я обычно также использую временную таблицу.Вы можете использовать выходной параметр, чтобы вернуть общее количество записей.Операторы case в select позволяют сортировать данные по определенным столбцам без необходимости прибегать к динамическому SQL.
--Declaration--
--Variables
@StartIndex INT,
@PageSize INT,
@SortColumn VARCHAR(50),
@SortDirection CHAR(3),
@Results INT OUTPUT
--Statements--
SELECT @Results = COUNT(ID) FROM Customers
WHERE FirstName LIKE '%a%'
SET @StartIndex = @StartIndex - 1 --Either do this here or in code, but be consistent
CREATE TABLE #Page(ROW INT IDENTITY(1,1) NOT NULL, id INT, sorting_1 SQL_VARIANT, sorting_2 SQL_VARIANT)
INSERT INTO #Page(ID, sorting_1, sorting_2)
SELECT TOP (@StartIndex + @PageSize)
ID,
CASE
WHEN @SortColumn='FirstName' AND @SortDirection='ASC' THEN CAST(FirstName AS SQL_VARIANT)
WHEN @SortColumn='LastName' AND @SortDirection='ASC' THEN CAST(LastName AS SQL_VARIANT)
ELSE NULL
END AS sort_1,
CASE
WHEN @SortColumn='FirstName' AND @SortDirection='DES' THEN CAST(FirstName AS SQL_VARIANT)
WHEN @SortColumn='LastName' AND @SortDirection='DES' THEN CAST(LastName AS SQL_VARIANT)
ELSE NULL
END AS sort_2
FROM (
SELECT
CustomerId AS ID,
FirstName,
LastName
FROM Customers
WHERE
FirstName LIKE '%a%'
) C
ORDER BY sort_1 ASC, sort_2 DESC, ID ASC;
SELECT
ID,
Customers.FirstName,
Customers.LastName
FROM #Page
INNER JOIN Customers ON
ID = Customers.CustomerId
WHERE ROW > @StartIndex AND ROW <= (@StartIndex + @PageSize)
ORDER BY ROW ASC
DROP TABLE #Page
Я считаю, что вам нужно будет выполнить отдельный запрос, чтобы выполнить это без необходимости.
Я смог сделать это на своей предыдущей должности, воспользовавшись помощью этой страницы:Пейджинг в DotNet 2.0
У них также есть возможность отдельно подсчитывать количество строк.
Вот что я делаю для пейджинга:Все мои большие запросы, которые необходимо разбивать на страницы, кодируются как вставки во временную таблицу.Во временной таблице есть поле идентификатора, которое будет действовать аналогично функции row_number(), упомянутой выше.Я сохраняю количество строк во временной таблице в выходном параметре, чтобы вызывающий код знал, сколько всего записей.Вызывающий код также указывает, какая страница ему нужна и сколько строк на странице выбираются из временной таблицы.
Самое приятное в этом то, что у меня также есть ссылка «Экспорт», которая позволяет вам получить все строки из отчета, возвращаемые в виде CSV, над каждой сеткой в моем приложении.Эта ссылка использует ту же хранимую процедуру:вы просто возвращаете содержимое временной таблицы вместо выполнения логики подкачки.Это успокаивает пользователей, которые ненавидят пейджинг и хотят видеть все, и хотите отсортировать его миллионом разных способов.