Каков наилучший способ разбить результаты на страницы в SQL Server

Вот полный подход @tjunglc с циклом:

protected function getPrevNext($aArray,$key)
{
    $aKeys = array_keys($aArray); //every element of aKeys is obviously unique
    $aIndices = array_flip($aKeys); //so array can be flipped without risk
    $i = $aIndices[$key]; //index of key in aKeys
    if ($i > 0) $prev = $aArray[$aKeys[$i-1]]; //use previous key in aArray
    if ($i < count($aKeys)-1) $next = $aArray[$aKeys[$i+1]]; //use next key in aArray
    if (!isset($prev)) $prev = end($aArray);
    if (!isset($next)) $next = reset($aArray);
    return array($prev,$next);
}

Oh и thankx @tjunglc для этого:)

417
задан Lukas Eder 26 October 2013 в 18:20
поделиться

4 ответа

Получение общего количества результатов и разбиения на страницы является двумя различными операциями. Ради этого примера давайте предположим, что запрос, с которым Вы имеете дело,

SELECT * FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate

В этом случае, Вы определили бы общее количество использования результатов:

SELECT COUNT(*) FROM Orders WHERE OrderDate >= '1980-01-01'

..., который может казаться неэффективным, но на самом деле довольно производителен, принимая все индексы и т.д., правильно настраиваются.

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

SELECT  *
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *
          FROM      Orders
          WHERE     OrderDate >= '1980-01-01'
        ) AS RowConstrainedResult
WHERE   RowNum >= 1
    AND RowNum < 20
ORDER BY RowNum

Это возвратит строки 1-19 из исходного запроса. Прохладная вещь здесь, специально для веб-приложений, состоит в том, что Вы не должны сохранять состояние, кроме номеров строк, которые будут возвращены.

423
ответ дан mdb 26 October 2013 в 18:20
поделиться

Вы не определили язык, ни какой драйвер Вы используете. Поэтому я описываю его абстрактно.

  • Создают набор результатов с возможностью прокрутки / набор данных. Это потребовало, чтобы основное устройство на переходе таблицы (таблиц)
  • до конца
  • запросило, чтобы переход количества
  • строки к запуску страницы
  • просмотрел строки путем прокрутки до конца страницы
-17
ответ дан Vinko Vrsalovic 26 October 2013 в 18:20
поделиться

Существует хороший обзор различных разбиений памяти на страницы в http://www.codeproject.com/KB/aspnet/PagingLarge.aspx

, я использовал метод ROWCOUNT довольно часто главным образом с SQL Server 2000 (будет работать с 2 005 & 2008 также, просто измерьте уровень по сравнению с ROW_NUMBER), это - молния быстро, но необходимо удостовериться, что отсортированный столбец (столбцы) имеет (главным образом) уникальные значения.

15
ответ дан Fabio Milheiro 26 October 2013 в 18:20
поделиться

Что ж, я использовал следующий пример запроса в своей базе данных SQL 2000, он хорошо работает и для SQL 2005. Он дает вам возможность динамического упорядочивания с использованием нескольких столбцов. Я говорю вам ... это мощно :)

    ALTER PROCEDURE [dbo].[RE_ListingReports_SelectSummary] 

@CompanyID  int,
@pageNumber     int,
@pageSize   int, 
@sort       varchar(200)
AS

DECLARE @sql nvarchar(4000)
DECLARE @strPageSize nvarchar(20)
DECLARE @strSkippedRows nvarchar(20)
DECLARE @strFields nvarchar(4000)
DECLARE @strFilter nvarchar(4000)
DECLARE @sortBy nvarchar(4000)
DECLARE @strFrom nvarchar(4000)
DECLARE @strID nvarchar(100)

If(@pageNumber < 0)
  SET @pageNumber = 1
SET @strPageSize = CAST(@pageSize AS varchar(20)) 
SET @strSkippedRows = CAST(((@pageNumber - 1) * @pageSize) AS varchar(20))-- For    example if pageNumber is 5  pageSize is 10, then SkippedRows = 40.
SET @strID = 'ListingDbID'
SET @strFields = 'ListingDbID,
ListingID,  
[ExtraRoom]
'
SET @strFrom = ' vwListingSummary '

SET @strFilter = ' WHERE
        CompanyID = ' + CAST(@CompanyID As varchar(20)) 
End
SET @sortBy = ''
if(len(ltrim(rtrim(@sort))) > 0)
SET @sortBy = ' Order By ' + @sort

-- Total Rows Count

SET @sql =  'SELECT Count(' + @strID + ')  FROM ' + @strFROM + @strFilter
EXEC sp_executesql @sql

--// This technique is used in a Single Table pagination
SET @sql = 'SELECT ' + @strFields + ' FROM ' + @strFROM +
    ' WHERE ' + @strID +  ' IN ' + 
   '  (SELECT TOP ' + @strPageSize + ' ' + @strID + ' FROM ' + @strFROM + @strFilter + 
             ' AND  ' + @strID + ' NOT IN ' + '
          (SELECT TOP ' + @strSkippedRows + ' ' + @strID + ' FROM ' + @strFROM + @strFilter + @SortBy + ') ' 
   + @SortBy + ') ' + @SortBy
Print @sql 
EXEC sp_executesql @sql

Самое приятное то, что sp_executesql кэширует последующие вызовы при условии, что вы передаете те же параметры, то есть генерируете тот же текст sql.

0
ответ дан 22 November 2019 в 23:11
поделиться
Другие вопросы по тегам:

Похожие вопросы: