web-dev-qa-db-ja.com

1つの選択ステートメントで、特定の範囲の行を返す

私はこのようないくつかの表現を探しています(SQL Server 2008を使用)

SELECT TOP 10 columName FROM tableName

しかし、その代わりに、10から20までの値が必要です。そして、SELECTステートメントを1つだけ使用してそれを行う方法はあるのでしょうか。

たとえば、これは役に立たない:

SELECT columName FROM
(SELECT ROW_NUMBER() OVER(ORDER BY someId) AS RowNum, * FROM tableName) AS alias
WHERE RowNum BETWEEN 10 AND 20

括弧内の選択はすでにすべての結果を返しているので、パフォーマンスのためにそれを回避しようとしています。

14
user1823901

すべての行のソートを含まないrow_numberのトリックがあります。

これを試して:

SELECT columName
FROM (SELECT ROW_NUMBER() OVER(ORDER BY (select NULL as noorder)) AS RowNum, *
      FROM tableName
     ) as alias
WHERE RowNum BETWEEN 10 AND 20

order byでは定数を使用できません。ただし、定数に評価される式を使用できます。 SQL Serverはこれを認識し、適切に列挙された、検出された行を返すだけです。

8
Gordon Linoff

SQL Server 2012を使用してフェッチ/スキップ!

SELECT SalesOrderID, SalesOrderDetailID, ProductID, OrderQty, UnitPrice, LineTotal
FROM AdventureWorks2012.Sales.SalesOrderDetail
OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

古いバージョンのsqlサーバーについて説明しているよりも優れたものはありません。おそらくCTEを使用しますが、違いを生む可能性はほとんどありません。

WITH NumberedMyTable AS
(
    SELECT
        Id,
        Value,
        ROW_NUMBER() OVER (ORDER BY Id) AS RowNumber
    FROM
        MyTable
)
SELECT
    Id,
    Value
FROM
    NumberedMyTable
WHERE 
    RowNumber BETWEEN @From AND @To  

または、上位10行を削除してから次の10行を取得することもできますが、私はそれを実行したいと思うだれでも2倍にします。

4
RAS

SQL Serverが内部クエリ全体を評価するのはなぜだと思いますか?ソート列にインデックスが付けられていると仮定すると、最初の20個の値を読み取るだけです。あなたが本当に緊張しているなら、これを行うことができます:

Select
  Id 
From (
  Select Top 20 -- note top 20
    Row_Number() Over(Order By Id) As RowNum,
    Id 
  From
    dbo.Test
  Order By
    Id
  ) As alias
Where
  RowNum Between 10 And 20
Order By
  Id

しかし、クエリプランはどちらの方法でも同じだと思います。

(本当に)アーロンのコメントに従って修正。

http://sqlfiddle.com/#!3/db162/6

3
Laurence

もう1つのオプション

SELECT TOP(11) columName
FROM dbo.tableName
ORDER BY
CASE WHEN ROW_NUMBER() OVER (ORDER BY someId) BETWEEN 10 AND 20 
     THEN ROW_NUMBER() OVER (ORDER BY someId) ELSE NULL END DESC
1

あなたが好きなように注文された一時テーブルを作成することができます:

SELECT ROW_NUMBER()OVER(ORDER BY someId)AS RowNum、* FROM tableName into ## tempTable ...

このようにして、行の順序付きリストを作成します。また、内部クエリを複数回実行する代わりに、以降の行番号でクエリを実行できます。

0
user3688672