programing

SQL Server의 행 간격띄우기

telebox 2023. 5. 7. 11:21
반응형

SQL Server의 행 간격띄우기

SQL Server에서 지정된 오프셋에서 결과를 가져올 수 있는 방법이 있습니까?예를 들어 다른 유형의 SQL 데이터베이스에서는 다음 작업을 수행할 수 있습니다.

SELECT * FROM MyTable OFFSET 50 LIMIT 25

51-75의 결과를 얻기 위해.이 구성은 SQL Server에 없는 것 같습니다.

상관없는 모든 행을 로드하지 않고 어떻게 이 작업을 수행할 수 있습니까?감사합니다!

사용하지 않을 것입니다.SELECT *실제로 원하는 열을 모두 지정할 수도 있습니다.

SQL Server 2005 이상

SELECT col1, col2 
FROM (
    SELECT col1, col2, ROW_NUMBER() OVER (ORDER BY ID) AS RowNum
    FROM MyTable
) AS MyDerivedTable
WHERE MyDerivedTable.RowNum BETWEEN @startRow AND @endRow

SQL Server 2000

SQL Server 2000에서 대규모 결과 집합을 효율적으로 페이징

대규모 결과 집합을 통한 보다 효율적인 페이징 방법

키 하고 든모페를순로처면려이리하페전표이에다시지사마니합용된다지을음키를 사용하면 .TOP (25) ... WHERE Key > @last_key ORDER BY Key이 방법을 효율적으로 검색할 수 있는 적합한 인덱스가 존재하는 경우 가장 성능이 좋은 방법이 될 수 있고 그렇지 않은 경우 API 커서가 존재할 수 있습니다.

SQL 2005 - SQL Server 2005 - 2008 R2일 것입니다.ROW_NUMBER그리고.BETWEEN

SQL Server 2012+의 경우 향상된 ORDER BY 절을 사용할 수 있습니다.

SELECT  *
FROM     MyTable 
ORDER BY OrderingColumn ASC 
OFFSET  50 ROWS 
FETCH NEXT 25 ROWS ONLY 

그러나 옵션이 얼마나수행될지는 두고 봐야 합니다.

이것은 한 가지 방법입니다(SQL2000).

SELECT * FROM
(
    SELECT TOP (@pageSize) * FROM
    (
        SELECT TOP (@pageNumber * @pageSize) *
        FROM tableName 
        ORDER BY columnName ASC
    ) AS t1 
    ORDER BY columnName DESC
) AS t2 
ORDER BY columnName ASC

그리고 이것은 다른 방법입니다 (SQL 2005)

;WITH results AS (
    SELECT 
        rowNo = ROW_NUMBER() OVER( ORDER BY columnName ASC )
        , *
    FROM tableName 
) 
SELECT * 
FROM results
WHERE rowNo between (@pageNumber-1)*@pageSize+1 and @pageNumber*@pageSize

사용할 수 있습니다.ROW_NUMBER()원하는 것을 얻을 수 있는 기능:

SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY id) RowNr, id FROM tbl) t
WHERE RowNr BETWEEN 10 AND 20

이 .OFFSET .. FETCH Server 2012를 .ORDER BY기둥.

만약 당신이 정말로 어떤 명시적인 열도 가지고 있지 않다면, 당신은 그것을 통과할 수 있습니다.ORDER BY열(다른 사용자가 제안한 대로)은 다음과 같은 트릭을 사용할 수 있습니다.

SELECT * FROM MyTable 
ORDER BY @@VERSION 
OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY

또는

SELECT * FROM MyTable 
ORDER BY (SELECT 0)
OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY

사용자가 주문을 명시적으로 지정하지 않을 때 jOOQ에서 사용하고 있습니다.그러면 추가 비용 없이 무작위로 주문할 수 있습니다.

데이터 열이 더 많고 더 큰 테이블의 경우 다음을 선호합니다.

SELECT 
  tablename.col1,
  tablename.col2,
  tablename.col3,
  ...
FROM
(
  (
    SELECT
      col1
    FROM 
    (
      SELECT col1, ROW_NUMBER() OVER (ORDER BY col1 ASC) AS RowNum
      FROM tablename
      WHERE ([CONDITION])
    )
    AS T1 WHERE T1.RowNum BETWEEN [OFFSET] AND [OFFSET + LIMIT]
  )
  AS T2 INNER JOIN tablename ON T2.col1=tablename.col1
);

-

[CONDITION] can contain any WHERE clause for searching.
[OFFSET] specifies the start,
[LIMIT] the maximum results.

ROW_NUMBER 함수는 하나의 열만 훑어보고 일치하는 행만 모든 열과 함께 반환되므로 BLOB와 같은 큰 데이터가 있는 테이블에서 훨씬 더 나은 성능을 발휘합니다.

페이지 관리자에 대한 내 선택

SELECT TOP @limit * FROM (
   SELECT ROW_NUMBER() OVER (ORDER BY colunx ASC) offset, * FROM (

     -- YOU SELECT HERE
     SELECT * FROM mytable


   ) myquery
) paginator
WHERE offset > @offset

이렇게 하면 페이지화가 해결됩니다 ;)

SELECT TOP 75 * FROM MyTable
EXCEPT 
SELECT TOP 50 * FROM MyTable

당신의 버전에 따라 당신은 그것을 직접 할 수는 없지만, 당신은 당신과 같은 진부한 것을 할 수 있습니다.

select top 25 *
from ( 
  select top 75 *
  from   table 
  order by field asc
) a 
order by field desc 

여기서 '필드'는 키입니다.

다음은 SQL Server 2012에서 처음 50개의 레코드 작업을 제외한 25개의 레코드를 표시합니다.

SELECT * FROM MyTable ORDER BY ID OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY;

요구 사항에 따라 ID를 대체할 수 있습니다.

사용시주합니다야해의를 .ROW_NUMBER() OVER (ORDER BY)성능이 상당히 나쁘기 때문에 진술.을 일반테사용때도마찬다니입과 함께 입니다.ROW_NUMBER()그것은 훨씬 더 심각합니다.ID가 있는 테이블 변수를 사용하여 페이지 번호를 제공하는 것보다 약간 더 빠르다는 것이 증명된 다음 스니펫을 사용하고 있습니다.

DECLARE @Offset INT = 120000
DECLARE @Limit INT = 10

DECLARE @ROWCOUNT INT = @Offset+@Limit
SET ROWCOUNT @ROWCOUNT

SELECT * FROM MyTable INTO #ResultSet
WHERE MyTable.Type = 1

SELECT * FROM
(
    SELECT *, ROW_NUMBER() OVER(ORDER BY SortConst ASC) As RowNumber FROM
    (
        SELECT *, 1 As SortConst FROM #ResultSet
    ) AS ResultSet
) AS Page
WHERE RowNumber BETWEEN @Offset AND @ROWCOUNT

DROP TABLE #ResultSet

저는 이 기술을 페이지화에 사용합니다.모든 행을 가져오지 않습니다.예를 들어, 페이지에 상위 100개 행을 표시해야 하는 경우 where 절이 있는 100개만 가져옵니다.SQL의 출력에는 고유한 키가 있어야 합니다.

표에는 다음이 있습니다.

ID, KeyId, Rank

둘 이상의 KeyId에 대해 동일한 순위가 할당됩니다.

은 SQL »select top 2 * from Table1 where Rank >= @Rank and ID > @Id

처음으로 둘 다 0을 넘겼습니다.두 번째는 1과 14를 통과했습니다. 세 번째는 2와 6을 통과했습니다.

10번째 레코드 Rank & Id의 값은 다음으로 전달됩니다.

11  21  1
14  22  1
7   11  1
6   19  2
12  31  2
13  18  2

이는 시스템에 대한 스트레스를 최소화합니다.

SqlServer2005에서는 다음을 수행할 수 있습니다.

DECLARE @Limit INT
DECLARE @Offset INT
SET @Offset = 120000
SET @Limit = 10

SELECT 
    * 
FROM
(
   SELECT 
       row_number() 
   OVER 
      (ORDER BY column) AS rownum, column2, column3, .... columnX
   FROM   
     table
) AS A
WHERE 
 A.rownum BETWEEN (@Offset) AND (@Offset + @Limit-1) 

레코드를 주문하는 데 시간을 낭비하지 않고 이 작업을 수행하는 가장 좋은 방법은 다음과 같습니다.

select 0 as tmp,Column1 from Table1 Order by tmp OFFSET 5000000 ROWS FETCH NEXT 50 ROWS ONLY

!1초도 걸리지 않습니다!
대형 테이블에 가장 적합한 솔루션입니다.

SQL Server 2012(11.x) 이상 및 Azure SQL Database에서는 "fetch_row_count_expression"도 사용할 수 있으며 이와 함께 ORDER BY 절도 사용할 수 있습니다.

USE AdventureWorks2012;  
GO  
-- Specifying variables for OFFSET and FETCH values    
DECLARE @skip int = 0  , @take int = 8;  
SELECT DepartmentID, Name, GroupName  
FROM HumanResources.Department  
ORDER BY DepartmentID ASC   
    OFFSET @skip ROWS   
    FETCH NEXT @take ROWS ONLY; 

https://learn.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-ver15

주 OFFSET 쿼리 식에서 행 반환을 시작하기 전에 건너뛸지정합니다.시작 행 번호가 아닙니다.따라서 첫 번째 레코드를 포함하려면 0이어야 합니다.

저는 이 답변을 한참 동안 검색했는데(일반 쿼리에 대해) LOWCOUNT 및 커서를 사용하고 TOP 또는 임시 테이블 없이 SQL Server 2000+에서 다른 방법을 찾았습니다.

SET ROWCOUNT [OFFSET+LIMIT]결과를 제한하고 커서를 사용하여 원하는 행으로 직접 이동한 다음 끝을 '루프'할 수 있습니다.

그래서 당신의 질문은 다음과 같습니다.

SET ROWCOUNT 75 -- (50 + 25)
DECLARE MyCursor SCROLL CURSOR FOR SELECT * FROM pessoas
OPEN MyCursor
FETCH ABSOLUTE 50 FROM MyCursor -- OFFSET
WHILE @@FETCH_STATUS = 0 BEGIN
    FETCH next FROM MyCursor
END
CLOSE MyCursor
DEALLOCATE MyCursor
SET ROWCOUNT 0

방법 1:

여기서는 주문이 중요한 것 같습니다.

오프셋 전에 제한을 가져오는 것이 효과적인 것 같습니다.

SELECT *
FROM MyTable
LIMIT 25
OFFSET 50

방법 2:.

제한만 도 있습니다.
LIMIT는 두 개의 값을 사용합니다.
번째 : 값 첫째 : 셋오값 프번
번째:행 수 째 : 수없음두


내 테이블에서
LIMIT(오프셋 값), (행 수 없음)

SELECT *
FROM MyTable
LIMIT 50, 25

언급URL : https://stackoverflow.com/questions/187998/row-offset-in-sql-server

반응형