2016-09-03 4 views
1

私は従業員のテーブルを持っています。 EmployeeName(varchar(100))とSalaryフィールド(deciaml)があります。すべてのレコードがソートされた順番であり、私は第11番目の従業員から20番目の従業員までレコードを取得しようとしていました。私はこのデータを得るための複数の単純な方法があることを知っています。私は3〜4種類の方法でそれをやっています。しかし、私が試した方法の1つは動作していませんし、予期しないデータを再試行します。SQLサーバーでTOPが予期しない行を返す

データスクリプト:レコードをフェッチする

declare @counter int = 1 
while(@counter <= 50) 
begin 
    insert into Employee (name,salary) select CONCAT('name - ',@counter),100*@counter; 
    set @counter += 1; 
end 

Select * from Employee 

問合せ:

select top(10) * from (
Select Top(20)* from Employee 
) as t order by t.id desc 

説明:以下は、私が使用しているスクリプトですまず、私は最初の20人の従業員のレコードを取得していますが、 TOP(20)を使用します。それから、20人の従業員のデータを降順で注文し、次にTOP(10人)の従業員を取得しようとしています。それは、私が従業員を11-20から返すことを想定していた(descinduingまたはascindingの任意の順序で)。しかし、それは50-41から従業員を返します。どうして?

+0

を。それは20項目を返す可能性があります。 –

+1

ORDER BYなしでTOPを使用しないでください。 –

+0

@SamKuhmonenありがとうサミ、今私はそれが私のクエリで間違っている。 – sunil20000

答えて

3

TOPORDER BYは不確定行を返します。あなたは必要とするサブクエリだけでなく、外側のクエリでORDER BY

select top(10) e.* 
from (Select Top(20) e.* 
     from Employee e 
     order by t.id asc 
    ) e 
order by e.id desc; 

あなたの質問はこれを含んでいます。「すべてのレコードがソートされています」。リレーショナルデータベースでは意味がありません。 SQLテーブルは、順序付けられていないセットを表します。結果セットは、ORDER BYを使用した場合にのみ注文されます。

注:クラスタ化インデックスを使用すると、テーブル内のレコードの物理記憶域に順序付けが行われます。単一のプロセッサマシン(または単一の実行スレッドを使用するクエリ)では、実際にはの結果がクラスタ化キーの順序に従って返されます。しかし、依然としてその動作に頼るべきではありませんし、順序を気にするときは明示的にORDER BYを使用してください。

+0

ありがとう、ゴードン、これは私が探していたものです。あなたのクエリの小さな変更ではなく、私が昇順を使用する場合は降順を使用して、それは期待される結果を生成します。 – sunil20000

1

は、SQL Server 2012を使用している場合は、その理由だけでこのようなものは使用しない:あなたは、内側のクエリでは、任意の順序を言っていない

SELECT * 
FROM Employee e 
ORDER BY e.id 
OFFSET 10 ROWS 
FETCH NEXT 10 ROWS ONLY 
+0

ありがとうキャメロン、しかし私はすでに動作しているクエリを持っています。私が探しているのは、私が上記の質問をしていない理由です。 – sunil20000

関連する問題