이 쿼리로 페이징 (건너 뛰기 / 취소) 기능 구현


138

나는 SQL에서 커스텀 페이징을 구현하는 방법, 예를 들어 이와 같은 기사 를 읽는 방법에 대해 조금 이해하려고 노력했습니다 .

완벽하게 작동하는 다음 쿼리가 있습니다. 그러나이 페이징을 구현하고 싶습니다.

SELECT TOP x PostId FROM ( SELECT PostId, MAX (Datemade) as LastDate
 from dbForumEntry 
 group by PostId ) SubQueryAlias
 order by LastDate desc

내가 원하는게 뭐야

관련 항목이있는 포럼 게시물이 있습니다. 최근에 추가 한 항목이있는 게시물을 가져 와서 최근 토론 된 게시물을 선택할 수 있습니다.

이제 "top 10"대신 "최근에 활성화 된 10 ~ 20 개의 게시물"을 얻을 수 있기를 원합니다.

내가 무엇을 시도

나는 기사에서 ROW 함수를 구현하려고했지만 실제로 운이 없다.

그것을 구현하는 방법에 대한 아이디어가 있습니까?

답변:


288

SQL Server 2012 에서는 매우 쉽습니다.

SELECT col1, col2, ...
 FROM ...
 WHERE ... 
 ORDER BY -- this is a MUST there must be ORDER BY statement
-- the paging comes here
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

ORDER BY를 건너 뛰려면

SELECT col1, col2, ...
  ...
 ORDER BY CURRENT_TIMESTAMP
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

(차라리 그것을 핵으로 표시하고 싶지만 NHibernate에 의해 사용됩니다. 현명하게 선택된 열을 ORDER BY로 사용하는 것이 선호됩니다)

질문에 대답하기 위해 :

--SQL SERVER 2012
SELECT PostId FROM 
        ( SELECT PostId, MAX (Datemade) as LastDate
            from dbForumEntry 
            group by PostId 
        ) SubQueryAlias
 order by LastDate desc
OFFSET 10 ROWS -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

새로운 키워드 offsetfetch next(SQL 표준을 따르는) 소개되었습니다.

하지만 사용하지 않는 것으로 추측 2012 SQL 서버를 오른쪽 ? 이전 버전에서는 약간 (약간) 어렵다. 모든 SQL Server 버전에 대한 비교 및 ​​예는 다음과 같습니다. here

따라서 이것은 SQL Server 2008 에서 작동 할 수 있습니다 .

-- SQL SERVER 2008
DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 10,@End = 20;


;WITH PostCTE AS 
 ( SELECT PostId, MAX (Datemade) as LastDate
   ,ROW_NUMBER() OVER (ORDER BY PostId) AS RowNumber
   from dbForumEntry 
   group by PostId 
 )
SELECT PostId, LastDate
FROM PostCTE
WHERE RowNumber > @Start AND RowNumber <= @End
ORDER BY PostId

고마워요! 정말 좋은 답변입니다! SQL 2008에 대해서만 질문하십시오. ORDER BY가 WHERE보다 먼저 발생하기를 원합니다. 현재 하위 세트를 정렬 할 것이지만 전체 세트에서 무언가를 선택하고 싶습니다 ... 어떤 아이디어? :) 다시 한번 감사
라스 Holdgaard

2
내가 당신을 올바르게 이해한다면 LastDate로 정렬하고 싶습니까? 그런 다음 OVER () 절을 ROW_NUMBER () OVER (ORDER BY MAX (Datemade) desc ) 방식으로 변경할 수 있습니다 . 마지막 ORDER BY PostId를 제거하십시오 . 이제 CTE는 필요에 따라 '부드럽게'정렬되어야합니다. 옳은?
Radim Köhler

1
감사합니다. 2012 샘플에 대한 참고 사항, order by는 필수입니다. order by clause없이 시도했지만 오류가 발생했습니다. "잘못된 구문"은 MSDN 구문을 살펴보고 그 순서가 필수임을 알 때까지 무엇이 잘못되었는지 알 수 없었습니다. .
Esen

첫 번째 행은 1 또는 0입니까? 는 WHERE해야 WHERE RowNumber >= @Start AND RowNumber < @End하는 경우 처음 1000 개 행을 얻을 @Start0이고 @End1000?
CWSpear

1
정말 감사합니다
Mafii



5

SQL 2008

Radim Köhler의 답변이 효과가 있지만 여기에 더 짧은 버전이 있습니다.

select top 20 * from
(
select *,
ROW_NUMBER() OVER (ORDER BY columnid) AS ROW_NUM
from tablename
) x
where ROW_NUM>10

출처 : https://forums.asp.net/post/4033909.aspx


-1

다음과 같이 페이지 매김에 중첩 쿼리 를 사용할 수 있습니다 .

CustomerId기본 키인 4 행에서 8 행으로 페이징 .

SELECT Top 5 * FROM Customers
WHERE Country='Germany' AND CustomerId Not in (SELECT Top 3 CustomerID FROM Customers
WHERE Country='Germany' order by city) 
order by city;
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.