SQL Server SELECT LAST N 행


139

이것은 알려진 질문이지만 내가 찾은 최고의 솔루션은 다음과 같습니다.

SELECT TOP N *
FROM MyTable
ORDER BY Id DESC

행이 많은 테이블이 있습니다. 시간이 많이 걸리기 때문에 해당 쿼리를 사용할 가능성은 없습니다. ORDER BY를 사용하지 않고 마지막 N 행을 선택하려면 어떻게해야합니까?

편집하다

질문에 대해 죄송합니다. 중복 된 질문


"last N"이란 무엇입니까? 순서가 없으면 "last N"은 의미가 없습니다. "마지막 N이 삽입 됨"을 의미하는 경우 SQL Server를 사용하여이를 제공 할 수 없습니다. ORDER BY 절을 사용해야합니다.
Daniel Renshaw

@Daniel Renshaw : SQL Server가 테이블 속도를 늦추기 때문에 모든 테이블을 주문하도록 강요하지 않고 테이블의 마지막 N
Diego

질문의 쿼리 가장 좋습니다. id인덱스 된 경우 해당 인덱스를 반대로 스캔하고 처음 5 개 행 이후에 중지합니다. 색인화되지 않은 경우 TOP N정렬 을 수행해야합니다 . 이것은 다른 방법보다 나쁘지 않습니다. 전체 테이블을 정렬하지는 않습니다 (전체 테이블을 스캔해야 함)
Martin Smith

답변:


38

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

1
ROW NUMBER BY PARTITION 기능도 정렬을 사용합니다. 각 레코드에 대해 행 번호를 지정하기 위해 테이블을 정렬해야합니다.
Sadhir

이것은 사실이지만 일종의 본질이 없으면 효과가 없을 것입니다. 가장 좋은 해결책은 위의 쿼리와 같은 것으로 주요 열을 인덱싱하는 것입니다.
JonVD

101

이 SQL을 사용하여 SQL Server가 마지막 N 개의 행을 선택하도록 할 수 있습니다.

select * from tbl_name order by id desc limit N;

2
버전 호환성은 어떻습니까?
Fractaliste

63
SQL Server에서는 작동하지 않습니다. MySQL, PostgreSQL 및 SQLite 기능처럼 보입니다.
Tim Friesen

3
열거 된 모든 제품은 명확하게 SQL 서버입니다. MS SQL Server에 대해 이야기하고 싶다면 왜 그렇게 말하지 않습니까?
gena2x

4
혼란스러워 질문에 "ORDER BY를 사용하지 않고"선택 쿼리를 만드는 방법을 묻는 질문에 답변의 선택 쿼리에 "순서"가 있습니다. 이것은 "주문"이없는 "주문"의 일종입니까?
Robert Sinclair

5
@ gena2x이 질문은 SQL Server로 태그되었습니다. 이 태그는 Microsoft SQL Server를 나타냅니다.
Martin Smith

51

JonVD의 코드를 테스트했지만 매우 느립니다.

이 코드는 0이 걸렸습니다.

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

4
행이 몇 개입니까? 매우 느릴 수있는 많은 행이있을 때
Diego

@Diego 왜 그런가요? OrderDate인덱싱 된 경우 쿼리 의 첫 번째 또는 마지막 N 개 행 을 선택하는 것이 본질적으로 동일해야 합니다. 나는 OrderDate삽입 된 주문과 상관 관계 가 있다는 것을 알고 있지만, 이것이 부작용이며 여전히 테이블 스캔이 필요합니까? (그리고 나는 그것이 OP 가 그들의 질문에 대한 더 나은 문구
속달

1
@Diego-왜 이것이 당신이 받아 들인 대답보다 느릴 것이라고 믿는가?
Martin Smith

2
행을 거꾸로 반환합니다. 그런 다음 원래 주문을 다시 받으려면 순서대로 다시 주문해야합니다.
Mark

15

테이블에서 마지막 행 수를 선택하려는 경우.

구문은 다음과 같습니다

 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 행을 얻을 수 있지만 순서는 descnding 방법을 보여줍니다

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

매우 일반적인 방법으로 SQL 서버를 지원하는 방법은 다음과 같습니다.

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

그리고 성능면에서 나쁘지 않습니다 (서버 시스템에서 10,000 개 이상의 레코드에 대해 1 초 미만)


1
10 만 레코드는 성능에 대해 신경 쓰지 않아도됩니다. 수백만 건의 레코드에 대해 이야기 할 때 성능에 대해 생각할 수 있습니다.
Dom84

6

"Id"가 색인되어 있습니까? 그렇지 않다면, 그것은 중요한 일입니다 (이미 색인되어 있다고 생각합니다).

또한 모든 열을 반환해야합니까? 실제로 ID 열의 색인에 의해 완전히 수용 될 수있는 더 작은 열의 하위 집합 만 필요한 경우 (예 : ID 열에 NONCLUSTERED 색인이 있고 다른 열이없는 경우) 속도가 크게 향상 될 수 있습니다. 인덱스에 포함 된 필드의 경우 실제로 클러스터링 된 인덱스에서 조회를 수행하여 나머지 열을 실제로 반환해야하므로 쿼리 비용이 많이들 수 있습니다. CLUSTERED 인덱스이거나 쿼리에 반환하려는 다른 모든 필드를 포함하는 NONCLUSTERED 인덱스이면 괜찮을 것입니다.


6

먼저 가장 많은 기록을 얻습니다.

 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 

4

여기없이 시도 할 수있는 order by것이 있지만 각 행이 고유해야한다고 생각합니다. N원하는 L행 수이고 테이블의 행 수입니다.

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

앞에서 언급했듯이 반환되는 행은 정의되어 있지 않습니다.

편집 : 이것은 실제로 개가 느립니다. 정말 가치가 없습니다.


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

2

이 쿼리는 마지막 N 개의 행을 올바른 순서로 반환하지만 성능이 좋지 않습니다.

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

2

마지막 값을 얻으려면 쿼리 끝에 desc를 orderby와 함께 사용하십시오.


1

이것은 질문에 잘 맞지 않을 수도 있지만…

OFFSET 절

OFFSET number절을 사용하면 여러 행 을 건너 뛰고 그 후에 행을 리턴 할 수 있습니다.

그 문서 링크는 Postgres에 있습니다. 이것이 Sybase / MS SQL Server에 적용되는지 모르겠습니다.


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에서 LIMIT를 지원하지 않습니다. 대부분의 경우 MAX (ID)를 얻은 다음 빼기 만하면됩니다.

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

ID가 순차적이지 않은 경우 10 개 미만의 레코드를 리턴합니다.


0

매우 큰 테이블 (1 억 백만 또는 10 억 백만 행)에서 MOST RECENT 행 을 쿼리하는 데 사용하는 기술 은 쿼리가 RECENT ROWS의 최신 "N"퍼센트 만 "읽기"로 제한하고 있습니다. 이것은 실제 응용 프로그램입니다. 예를 들어, 역사적이 아닌 최근 날씨 데이터, 최근 뉴스 피드 검색 또는 최근 GPS 위치 데이터 포인트 데이터에 대해이 작업을 수행합니다.

이것은이다 엄청난 성능 향상 당신이 당신의 행 예를 들어 테이블의 가장 최근의 TOP 5 %에 있음을 확실히 알고있는 경우. 따라서 테이블에 인덱스가 있어도 가능성은 1 억 + 1 억 + 10 억 개의 행이있는 테이블의 행 중 5 %로 제한됩니다. 특히 오래된 데이터에 물리적 디스크 읽기 가 필요 하고 논리적 메모리 읽기 가 필요한 경우에 특히 그렇습니다 .

이것은 SELECT TOP | PERCENT | 행을 선택하지 않고 검색 할 데이터 부분을 제한하기 때문에 제한합니다.

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

사용하지 않고 마지막 3 행을 표시하려면 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
예측 가능한 결과를 제공하지 않습니다. Sql Server MSDN 문서 ( msdn.microsoft.com/en-us/library/ms189463.aspx ) 에 따르면 : "TOP을 ORDER BY 절과 함께 사용하면 결과 집합이 첫 N 개의 순서로 제한됩니다. 그렇지 않으면 처음 N 개의 행 수를 정의되지 않은 순서로 반환합니다. "
caveman_dick

-1

EXCEPT구문을 사용해보십시오 .
이 같은:

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

@Prafulla Sutradhar
DMK

-1

어쩌면 조금 늦었지만 여기에 귀하의 질문을 해결하는 간단한 선택이 있습니다.

SELECT * FROM "TABLE" T ORDER BY "T.ID_TABLE" DESC LIMIT 5;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.