SQL Server 2008 でページングを実装するより効率的な方法を探しています。
@from から @to までの結果セット行をスコア値順に取得する必要がありますが、特定の @from および @to 行のスコア値と一致する @from および @to の直前と直後のすべての行も取得する必要があります。たとえば、これは次の 2 つのクエリのいずれかのようになります。
注意: スコア値は一意ではなく、インデックス化されておらず、事前に並べ替えられた形式でクエリの残りの部分に提供されていません。
a) (実際には、この最初の例で必要な結果が得られるとは限りません。なぜなら、2 つのサブクエリの order by が同じ順序になるとは限らないからです。しかし、何を理解するためにサブクエリのオーダーバイが同一であることをこの例についてのみ考慮してください)
select *
from (
select top (@to) * with ties
from result_set
order by score desc
) tt
union
select
from (
select top (@to - @from + 1) * with ties
from (
select top (@to) *
result_set
order by score desc
) tt
order by score asc
) tt
order by score desc
また
b)
/*EDIT: nested the rank() window function and related where criteria one level deeper than
the count(*), as this gave me significant (25%) decrease in runtime with my data, and just
kinda makes sense.*/
select score
from (
select
score,
myrank,
count(*) over (partition by score) frequency
from (
select
score,
rank() over (order by score desc) myrank
from result_set
) tt
where myrank <= @to
) tt
where @from <= myrank + frequency - 1
order by score desc
次のテスト CTE と組み合わせて構文 (b) を使用して、必要な結果を取得します。
with result_set (score) as (
select 0.5 union all
select 0.5 union all
select 0.2 union all
select 0.1 union all
select 0.55 union all
select 0.5 union all
select 0.1
)
ただし、分割されたウィンドウ関数には、2 つの入れ子になったループと 3 つの遅延スプール演算子が必要です。これのためのより効率的な構文はありますか?
現在の実際の実行計画は次のとおりです。