これは既知の質問ですが、私が見つけた最良の解決策は次のようなものです。
SELECT TOP N *
FROM MyTable
ORDER BY Id DESC
たくさんの行があるテーブルです。時間がかかるため、このクエリを使用することは不可能です。では、どうすればORDER BYを使わずに最後のN行を選択することができるのでしょうか。
編集
ROW NUMBER BY PARTITION機能を使用しても実行できます。良い例がここにあります:
NorthwindデータベースのOrdersテーブルを使用しています...今度は、Employee 5が出した最後の5つの注文を取得しましょう。
SELECT ORDERID, CUSTOMERID, OrderDate FROM ( SELECT ROW_NUMBER() OVER (PARTITION BY EmployeeID ORDER BY OrderDate DESC) AS OrderedDate,* FROM Orders ) as ordlist WHERE ordlist.EmployeeID = 5 AND ordlist.OrderedDate <= 5
このSQLを使用して、SQLサーバーに最後のN行を選択させることができます。
select * from tbl_name order by id desc limit N;
私はJonVDのコードをテストしましたが、とても遅い6秒だとわかりました。
このコードは0秒かかりました。
SELECT TOP(5) ORDERID, CUSTOMERID, OrderDate
FROM Orders where EmployeeID=5
Order By OrderDate DESC
テーブルから最後の行数を選択したい場合。
構文は次のようになります
select * from table_name except select top
(numbers of rows - how many rows you want)* from table_name
これらのステートメントは機能しますが、異なる方法です。君たちありがとう。
select * from Products except select top (77-10) * from Products
このようにして、最後の10行を取得することができますが、順番は降順になります。
select top 10 * from products
order by productId desc
select * from products
where productid in (select top 10 productID from products)
order by productID desc
select * from products where productID not in
(select top((select COUNT(*) from products ) -10 )productID from products)
"Id"はインデックスされていますか?そうでなければ、それはするべき重要なことです(私はそれが既に索引付けされていると思う)。
また、すべての列を返す必要がありますか?あなたが実際にIDカラムのインデックスによって完全に対応することができるカラムのより小さなサブセットを必要とするなら、あなたはスピードのかなりの改善を得ることができるかもしれません - 例えば。 Id列にNONCLUSTERED索引があり、他のフィールドが索引に含まれていない場合は、残りの列を実際に返すためにクラスター化索引をルックアップする必要があります。クエリのコストそれがCLUSTEREDインデックス、またはあなたがクエリで返したい他のすべてのフィールドを含むNONCLUSTEREDインデックスであるならば、あなたは問題ないはずです。
非常に一般的な方法で、そしてここでSQLサーバーをサポートすることは、
SELECT TOP(N) *
FROM tbl_name
ORDER BY tbl_id DESC
そして性能のために、それは悪くないです(サーバーマシンの10,000以上の記録のための1秒以下)
まず、あなたはほとんどからレコード数を得ます
Declare @TableRowsCount Int
select @TableRowsCount= COUNT(*) from <Your_Table>
その後 :
SQL Server 2012の場合
SELECT *
FROM <Your_Table> As L
ORDER BY L.<your Field>
OFFSET <@TableRowsCount-@N> ROWS
FETCH NEXT @N ROWS ONLY;
SQL Server 2008の場合
SELECT *
FROM
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS sequencenumber, *
FROM <Your_Table>
Order By <your Field>
) AS TempTable
WHERE sequencenumber > @TableRowsCount-@N
select * from (select top 6 * from vwTable order by Hours desc) T order by Hours
これはorder by
がなくても試すことができるものですが、各行が一意である必要があると思います。 N
は必要な行数です。L
はテーブル内の行数です。
select * from tbl_name except select top L-N * from tbl_name
前述のように、どの行が返されるかは未定義です。
編集:これは実際に犬遅いです。本当に価値がないです。
このクエリは最後のN行を正しい順序で返しますが、パフォーマンスは良くありません。
select *
from (
select top N *
from TableName t
order by t.[Id] desc
) as temp
order by temp.[Id]
最後の値を取得するには、クエリの末尾でdescとorderbyを使用します。
これは質問に完全には適さないかもしれませんが…
OFFSET number
句を使用すると、行数をスキップしてその後の行を返すことができます。
そのdocリンクはPostgresへのものです。これがSybase/MS SQL Serverに当てはまるかどうかわかりません。
非常に大きなテーブル内の MOST RECENT 行を照会するために使用する技法(1億以上または10億以上の行)は、最新の「N」パーセントの「最近の行」のみを照会の「読み取り」に制限しています。これは現実世界のアプリケーションです。例えば、私は歴史的でない最近の天気データ、最近のニュースフィード検索、最近のGPS位置データポイントデータに対してこれを行います。
たとえば、行がテーブルの最新の上位5%にあることが確実であれば、これは大幅なパフォーマンスの向上になります。テーブルにインデックスがある場合でも、1億以上または10億以上の行を持つテーブル内の行の5%に可能性が限定されます。これは、古いデータが物理ディスク readを必要とし、 Logical In Memory readだけではない場合に特に当てはまります。
これはSELECT TOPよりもはるかに効率的です。 PERCENT |行を選択するのではなく、検索するデータの部分を制限するだけなので、LIMITを使用します。
DECLARE @RowIdTableA BIGINT
DECLARE @RowIdTableB BIGINT
DECLARE @TopPercent FLOAT
-- Given that there is an Sequential Identity Column
-- Limit query to only rows in the most recent TOP 5% of rows
SET @TopPercent = .05
SELECT @RowIdTableA = (MAX(TableAId) - (MAX(TableAId) * @TopPercent)) FROM TableA
SELECT @RowIdTableB = (MAX(TableBId) - (MAX(TableBId) * @TopPercent)) FROM TableB
SELECT *
FROM TableA a
INNER JOIN TableB b ON a.KeyId = b.KeyId
WHERE a.Id > @RowIdTableA AND b.Id > @RowIdTableB AND
a.SomeOtherCriteria = 'Whatever'
DECLARE @MYVAR NVARCHAR(100)
DECLARE @step int
SET @step = 0;
DECLARE MYTESTCURSOR CURSOR
DYNAMIC
FOR
SELECT col FROM [dbo].[table]
OPEN MYTESTCURSOR
FETCH LAST FROM MYTESTCURSOR INTO @MYVAR
print @MYVAR;
WHILE @step < 10
BEGIN
FETCH PRIOR FROM MYTESTCURSOR INTO @MYVAR
print @MYVAR;
SET @step = @step + 1;
END
CLOSE MYTESTCURSOR
DEALLOCATE MYTESTCURSOR