Пейджинг результатов сложного запроса SQL Server - PullRequest
0 голосов
/ 04 марта 2011

Как лучше всего отобразить результаты сложного запроса в SQL Server 2005 и 2008?

Я придумал следующий подход:

  1. Выполните запрос, сохраните его результаты в табличной переменной или временной таблице.

  2. Используйте следующий код:

    DECLARE @Rows INT = (SELECT COUNT(*) FROM @TableVariable)
    
    DELETE TV
    FROM   @TableVariable TV
    JOIN   (SELECT TV2.PrimaryKey, ROW_NUMBER() OVER(...) AS RowNo
            FROM   @TableVariable TV2) N ON TV.PrimaryKey = TV2.PrimaryKey
    WHERE N.RowNo < @FromRow OR N.RowNo > @ToRow
    
    SELECT PrimaryKey, SomeComputedField, ...
    FROM   @TableVariable
    
    RETURN @Rows
    

Однако у меня нет никакого опыта разбивать огромные массивы данных на себя. Что могут предложить другие SO?

Ответы [ 2 ]

2 голосов
/ 04 марта 2011

Тело ХРАНЕННОЙ ПРОЦЕДУРЫ можно записать в виде:

;WITH rownums AS (
    SELECT  tempTable.[link], 
            ROW_NUMBER() OVER (ORDER BY tempTable.[link]) AS rownum 
    FROM    <temptable here> AS tempTable
)
SELECT  tempTable.link
FROM    <temptable here> AS tempTable
        INNER JOIN rownums AS rn
        ON  rn.[link]   =   drn.[link]
WHERE   rn.[rownum] BETWEEN @low AND @high

Тогда вам нужно будет указать ХРАНЕННУЮ ПРОЦЕДУРУ с диапазоном (@low и @high), и вам, конечно, понадобится временная таблица.

PS Кроме того, я думаю, что ваше объявление переменной будет работать только в 2008 году, если я правильно помню, 2005 не поддерживает создание и инициализацию одной строки.

1 голос
/ 04 марта 2011

Если ваш набор данных большой, @table не будет работать хорошо.Ваш row_number также может быть немного оптимизирован, чтобы не проходить мимо @ ToRow

JOIN   (SELECT TOP(@ToRow) TV2.PrimaryKey, ROW_NUMBER() OVER(...) AS RowNo
        FROM   @TableVariable TV2
        ORDER BY ... -- same clause as ROW_NUMBER()

Я бы пошел по маршруту Stored Proc, заполнив таблицу # (используя TOP, как показано выше), в то же времявремя либо SELECT INTO с использованием IDENTITY (int, 1,1), либо предварительного создания таблицы с идентификатором (кластеризованной), затем вместо DELETE и SELECT (2 ops) просто SELECT из #temptable на основе

WHERE id-column between x and y
...