SQL Server SELECT LAST N Satır


139

Bu bilinen bir soru ama bulduğum en iyi çözüm şöyle bir şey:

SELECT TOP N *
FROM MyTable
ORDER BY Id DESC

Çok sıralı bir masam var. Bu sorguyu kullanmak bir olasılık değildir, çünkü çok zaman alır. Peki ORDER BY kullanmadan son N satırı nasıl seçebilirim?

DÜZENLE

Üzgünüm, bu sorunun yinelenen sorusu


"Son N" ile kastedilen nedir? Bir emir olmadan, "son N" pek mantıklı değil. "Eklenecek son N" anlamına gelirse, bunu size vermek için SQL Server'a güvenemezsiniz - ORDER BY deyimi kullanmanız gerekir.
Daniel Renshaw

@Daniel Renshaw: gerçekten yavaş olur, çünkü tüm tabloyu sipariş SQL Server zorlamadan tablosunun son N
Diego

Sorunuzun sorgu olduğunu en iyi yol. Eğer iddizine sonra sadece ilk 5 satır sonra ters ve durma o dizini tarar. Dizine eklenmemişse, bir TOP Nsıralama yapması gerekir . Bu, bunu yapmanın diğer yollarından daha kötü olmayacaktır. Tüm tabloyu sıralamıyor (tüm tabloyu taraması gerekecek olsa da)
Martin Smith

Yanıtlar:


38

Bunu, SAYISA GÖRE NUMARALA özelliğini de kullanarak yapabilirsiniz. Harika bir örnek burada bulunabilir :

Northwind veritabanının Siparişler tablosunu kullanıyorum ... Şimdi Çalışan 5 tarafından verilen Son 5 siparişi alalım:

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

1
SAYISA GÖRE NUMARALA özelliği de bir sıralama kullanır .. her kayıt için satır numaraları atamak için tabloyu sıralamanız gerekir ...
Sadhir

Bu doğrudur, ancak bir tür doğa olmadan bu işe yaramaz, en iyi çözüm, vurulmakta olan ana sütunları endekslemek ve yukarıdaki sorgu gibi bir şeyle çalıştırmaktır.
JonVD

101

Bu SQL'i kullanarak SQL sunucusunun son N satırını seçmesini sağlayabilirsiniz:

select * from tbl_name order by id desc limit N;

2
Sürüm uyumluluğu hakkında ne dersiniz?
Fractaliste

63
Bu SQL Server'da çalışmaz. MySQL, PostgreSQL ve SQLite özelliği gibi görünüyor.
Tim Friesen

3
Tüm numaralandırılmış ürünler kesinlikle SQL sunucularıdır. MS SQL sunucusu hakkında konuşmak istiyorsanız, neden böyle adlandırmıyorsunuz?
gena2x

4
kafam karıştı, soru "SİPARİŞ BY kullanmadan" bir seçme sorgusu oluşturmak için nasıl soruyor ve cevabınızdaki seçme sorgusu "tarafından sıralama" vardır. Bu bir tür "sipariş" olmadan "sipariş" olmadan mı?
Robert Sinclair

5
@ gena2x bu soru SQL Server olarak etiketlenmiştir. Bu etiket, Microsoft SQL Server'a atıfta bulunur.
Martin Smith

51

JonVD'nin kodunu test ettim, ama çok yavaş olduğunu gördüm, 6s.

Bu kod 0 saniye sürdü.

SELECT TOP(5) ORDERID, CUSTOMERID, OrderDate    
FROM Orders where EmployeeID=5    
Order By OrderDate DESC

4
Kaç satır ?? REALY yavaş olabilecek çok sayıda satıra sahip olduğunuzda
Diego

@Diego Neden bu? Eğer var ettiyseniz OrderDateendeksli, ilk almaya esasen eşit hızlı olmalı veya son bir sorgunun N satır. OrderDateEklenen siparişle iyi bir ilişki olduğunu anlıyorum , ama bu en iyi ihtimalle bir yan etki ve yine de bir tablo taraması gerektiriyor, değil mi? (Ve OP'nin sorularının daha iyi ifade edilen bir
dupe'si

1
@Diego - Bunun neden cevapladığından daha yavaş olacağına inanıyorsun?
Martin Smith

2
Bu, satırları baş aşağı döndürür. Daha sonra orijinal siparişi geri almak için onlar tarafından yeniden sipariş vermeniz gerekir.
Mark

15

Bir tablodan son satır sayısını seçmek istiyorsanız.

Sözdizimi şöyle olacak

 select * from table_name except select top 
 (numbers of rows - how many rows you want)* from table_name

Bu ifadeler farklı şekillerde çalışır. sağolun beyler.

 select * from Products except select top (77-10) * from Products

Bu şekilde son 10 satırı elde edebilirsiniz, ancak sipariş azalan şekilde gösterilecektir

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)

7

Çok genel bir şekilde ve burada SQL sunucuyu desteklemek için

SELECT TOP(N) *
FROM tbl_name
ORDER BY tbl_id DESC

ve performans için kötü değil (Sunucu makinesinde 10.000'den fazla kayıt için bir saniyeden az)


1
iyi 10.000 kayıt, performans hakkında düşünmeniz gereken bir şey değildir. Milyonlarca kayıt hakkında konuşmaya başladığınızda, performans hakkında düşünmeye başlayabilirsiniz
Dom84

6

"Kimlik" dizine eklenmiş mi? Değilse, bu önemli bir şeydir (zaten endekslendiğinden şüpheleniyorum).

Ayrıca, TÜM sütunları döndürmeniz mi gerekiyor? Kimlik sütununda dizin tarafından TAM olarak sunulabilecek daha küçük bir sütun alt kümesine gerçekten ihtiyacınız varsa, örneğin, Kimlik sütununda NONCLUSTERED dizininiz varsa, başka hiçbir şey olmadan hızda önemli bir iyileşme elde edebilirsiniz. alanları, daha sonra geri döndürülecek sütunların geri kalanını almak için kümelenmiş dizinde bir arama yapmak zorunda kalacak ve bu da sorgunun maliyetinin büyük bir kısmını oluşturabilir. Bir CLUSTERED dizini veya sorguda döndürmek istediğiniz tüm diğer alanları içeren NONCLUSTERED dizini ise, iyi olmalısınız.


6

İlk önce en fazla rekor sayı

 Declare @TableRowsCount Int
 select @TableRowsCount= COUNT(*) from <Your_Table>

Ve sonra :

SQL Server 2012'de

SELECT *
FROM  <Your_Table> As L
ORDER BY L.<your Field>
OFFSET <@TableRowsCount-@N> ROWS
FETCH NEXT @N ROWS ONLY;

SQL Server 2008'de

SELECT *
FROM 
(
SELECT ROW_NUMBER() OVER(ORDER BY ID) AS sequencenumber, *
FROM  <Your_Table>
    Order By <your Field>
) AS TempTable
WHERE sequencenumber > @TableRowsCount-@N 

4

İşte bir şey olmadan deneyebileceğiniz bir şey order by ama bence her satırın benzersiz olmasını gerektiriyor. Nistediğiniz Lsatır sayısı, tablodaki satır sayısıdır.

select * from tbl_name except select top L-N * from tbl_name

Daha önce belirtildiği gibi, hangi satırların döndürüldüğü tanımlanmamıştır.

EDIT: bu aslında köpek yavaş. Gerçekten hiçbir değeri yok.


4
select * from (select top 6 * from vwTable order by Hours desc) T order by Hours

2

Bu sorgu son N satırı doğru sırada döndürür, ancak performansı düşük

select *
from (
    select top N *
    from TableName t
    order by t.[Id] desc
) as temp
order by temp.[Id]

2

son değerleri almak için sorgunun sonunda sırayla desc komutunu kullanın.


1

Bu soruya tam olarak uygun olmayabilir, ama…

OFFSET deyimi

OFFSET numberYantümce üzerinde atlamak sağlar numara satır ve ondan sonra satırları döndürür.

Bu doc ​​bağlantısı Postgres'e; Bu Sybase / MS SQL Server için geçerli olup olmadığını bilmiyorum.


1
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

1

MS t-sql içinde LIMIT desteklemiyor. Çoğu zaman ben sadece MAX (ID) almak ve sonra çıkarmak.

select * from ORDERS where ID >(select MAX(ID)-10 from ORDERS)

Kimlik sıralı olmadığında bu 10 kayıttan daha azını döndürür.


0

Çok büyük tablolarda (100+ milyon veya 1+ milyar satır) EN SON SON satırlarını sorgulamak için kullandığım bir teknik , sorguyu yalnızca son "N" yüzdesini "okumak" ile sınırlıyor. Bu gerçek dünya uygulamaları, örneğin bunu tarihi olmayan Son Hava Durumu Verileri veya son Haber akışı aramaları veya Son GPS konum veri noktası verileri için yapıyorum.

Satırlarınızın örneğin tablonun en son TOP% 5'inde olduğunu kesin olarak biliyorsanız , bu büyük bir performans artışıdır . Öyle ki, Tablolarda dizinler olsa bile, olasılıkları 100+ milyon veya 1+ milyar sıraya sahip tablolardaki satırların yalnızca% 5'i ile sınırlar. Bu, özellikle Eski Verilerin Yalnızca Bellekteki Mantıksal Değil için Fiziksel Disk okumaları gerektireceği durumdur. okumalar için .

Bu, SELECT TOP | YÜZDE | LIMIT, satırları seçmediğinden, yalnızca aranacak verinin bir kısmını sınırlandırdığından.

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'

-1

Son 3 satırı kullanmadan görüntülemek için order by:

select * from Lms_Books_Details where Book_Code not in 
 (select top((select COUNT(*) from Lms_Books_Details ) -3 ) book_code from Lms_Books_Details) 

1
Bu öngörülebilir sonuçlar sağlamayacaktır. Sql Server MSDN belgelerine ( msdn.microsoft.com/en-us/library/ms189463.aspx ) göre: "TOP, ORDER BY yan tümcesi ile birlikte kullanıldığında, sonuç kümesi, sipariş edilen ilk N sayısıyla sınırlıdır aksi takdirde, ilk N satır sayısını tanımsız bir sırayla döndürür. "
caveman_dick

-1

EXCEPTSözdizimini kullanmayı deneyin .
Bunun gibi bir şey:

   SELECT * 
    FROM   clientDetails 
    EXCEPT 
    (SELECT TOP (numbers of rows - how many rows you want) * 
     FROM   clientDetails) 

@Prafulla Sutradhar ile aynı cevap
DMK

-1

Belki biraz geç, ama burada sorunuzu çözen basit bir seçim.

SELECT * FROM "TABLE" T ORDER BY "T.ID_TABLE" DESC LIMIT 5;
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.