IT박스

SQL Server SELECT LAST N 행

itboxs 2020. 7. 11. 11:09
반응형

SQL Server SELECT LAST N 행


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

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 Server가 마지막 N 개의 행을 선택하도록 할 수 있습니다.

select * from tbl_name order by id desc limit N;

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

이 코드는 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 행을 얻을 수 있지만 순서는 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)

"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 

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

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

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

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


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

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

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

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


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

OFFSET 절

The OFFSET number clause enables you to skip over a number of rows and then return rows after that.

That doc link is to Postgres; I don't know if this applies to Sybase/MS SQL Server.


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

A technique I use to query the MOST RECENT rows in very large tables (100+ million or 1+ billion rows) is limiting the query to "reading" only the most recent "N" percentage of RECENT ROWS. This is real world applications, for example I do this for non-historic Recent Weather Data, or recent News feed searches or Recent GPS location data point data.

This is a huge performance improvement if you know for certain that your rows are in the most recent TOP 5% of the table for example. Such that even if there are indexes on the Tables, it further limits the possibilites to only 5% of rows in tables which have 100+ million or 1+ billion rows. This is especially the case when Older Data will require Physical Disk reads and not only Logical In Memory reads.

This is well more efficient than SELECT TOP | PERCENT | LIMIT as it does not select the rows, but merely limit the portion of the data to be searched.

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'

To display last 3 rows without using 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) 

Try using the EXCEPT syntax.
Something like this:

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

참고URL : https://stackoverflow.com/questions/4193705/sql-server-select-last-n-rows

반응형