주어진 오프셋에서 시작하여 결과를 얻는 방법이 SQL Server에 있습니까? 예를 들어, 다른 유형의 SQL 데이터베이스에서 다음을 수행 할 수 있습니다.
SELECT * FROM MyTable OFFSET 50 LIMIT 25
결과 51-75를 얻을 수 있습니다. 이 구문은 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
SELECT *는 테이블의 구조가 변경 되어도 쿼리는 계속 실행되지만 결과는 다릅니다. 열이 추가되면 유용 할 수 있습니다 (여전히 이름으로 이름을 사용해야하지만). 열이 삭제되거나 이름이 변경되면 변수가 초기화되지 않았기 때문에 SQL이 이상하게 작동하는 코드보다 SQL이 눈에 띄게 중단되는 것이 좋습니다.
당신은 단순히 이전 페이지에서 볼 수있는 마지막 키 값을 기억하고 사용하여 다음 순서에있는 모든 페이지를 처리 할 경우 TOP (25) ... WHERE Key > @last_key ORDER BY Key또는 - 적절한 인덱스이 효율적으로 탐색했습니다 될 수 있도록 존재하는 경우 실적이 가장 좋은 방법이 될 수 있는 API 커서 그렇지 않은 경우 .
SQL 서버 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
이 OFFSET .. FETCHSQL 서버 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 25 *
from (
select top 75 *
from table
order by field asc
) a
order by field desc
여기서 'field'가 핵심입니다.
다음은 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 개의 행을 표시해야하는 경우 100 with where 절만 가져옵니다. SQL 출력에는 고유 키가 있어야합니다.
테이블에는 다음이 있습니다.
ID, KeyId, Rank
둘 이상의 KeyId에 동일한 순위가 할당됩니다.
SQL은 select top 2 * from Table1 where Rank >= @Rank and ID > @Id
처음으로 나는 둘 다 0을 전달합니다. 두 번째 타임 패스 1 & 14. 세 번째 타임 패스 2와 6 ....
10 번째 레코드 순위 및 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)
@Offset + @Limit - 1않습니까? @Limit이 10이면 11 행을 반환합니다.
기록을 주문하는 데 시간을 낭비하지 않고 가장 좋은 방법은 다음과 같습니다.
select 0 as tmp,Column1 from Table1 Order by tmp OFFSET 5000000 ROWS FETCH NEXT 50 ROWS ONLY
1 초도 걸리지 않습니다!
큰 테이블에 가장 적합한 솔루션입니다.
나는이 답변을 잠시 동안 찾고 있었으며 (일반 쿼리의 경우) ROWCOUNT와 커서를 사용하고 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
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;
참고 OFFSET 쿼리 식에서 행을 반환하기 전에 건너 뛸 행 수를 지정합니다 . 시작 행 번호가 아닙니다. 따라서 첫 번째 레코드를 포함하려면 0이어야합니다.