SQL Server 2005 결과 페이징
-
08-06-2019 - |
문제
SQL Server 2005에서 결과를 어떻게 페이징합니까?
SQL Server 2000에서 시도해 보았지만 이를 수행할 수 있는 안정적인 방법이 없었습니다.이제 SQL Server 2005에 내장된 메소드가 있는지 궁금합니다.
예를 들어, 페이징이란 사용자 이름을 기준으로 사용자를 나열하는 경우 처음 10개의 레코드만 반환하고 그 다음에는 다음 10개의 레코드 등을 반환할 수 있기를 원한다는 것입니다.
어떤 도움이라도 주시면 감사하겠습니다.
해결책
당신이 사용할 수있는 the Row_Number()
기능.다음과 같이 사용됩니다:
SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
그로부터 다음과 같은 결과 세트가 생성됩니다. RowID
페이지 사이를 이동하는 데 사용할 수 있는 필드입니다.
SELECT *
FROM
( SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
) As RowResults
WHERE RowID Between 5 AND 10
등
다른 팁
하나의 명령문(총합과 페이징)으로 얻으려는 경우.절에 의한 분할에 대한 SQL Server 지원을 탐색해야 할 수도 있습니다(ANSI SQL 용어의 창 기능).Oracle에서 구문은 row_number()를 사용하는 위의 예와 동일하지만 페이징에서 반환된 각 행에 포함된 총 행 수를 가져오기 위해 절별로 파티션을 추가했습니다(총 행은 1,262개입니다).
SELECT rn, total_rows, x.OWNER, x.object_name, x.object_type
FROM (SELECT COUNT (*) OVER (PARTITION BY owner) AS TOTAL_ROWS,
ROW_NUMBER () OVER (ORDER BY 1) AS rn, uo.*
FROM all_objects uo
WHERE owner = 'CSEIS') x
WHERE rn BETWEEN 6 AND 10
나는 owner = 'CSEIS'이고 내 파티션은 소유자에 있습니다.결과는 다음과 같습니다.
RN TOTAL_ROWS OWNER OBJECT_NAME OBJECT_TYPE
6 1262 CSEIS CG$BDS_MODIFICATION_TYPES TRIGGER
7 1262 CSEIS CG$AUS_MODIFICATION_TYPES TRIGGER
8 1262 CSEIS CG$BDR_MODIFICATION_TYPES TRIGGER
9 1262 CSEIS CG$ADS_MODIFICATION_TYPES TRIGGER
10 1262 CSEIS CG$BIS_LANGUAGES TRIGGER
이에 대한 허용된 답변은 실제로 저에게 적합하지 않습니다. 작동하려면 한 번 더 후프를 거쳐야 했습니다.
답변을 시도해 봤을 때
SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
WHERE RowID Between 0 AND 9
RowID가 무엇인지 모른다고 불평하면서 실패했습니다.
다음과 같이 내부 선택으로 포장해야 했습니다.
SELECT *
FROM
(SELECT
Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName
FROM Users
) innerSelect
WHERE RowID Between 0 AND 9
그리고 그것은 효과가있었습니다.
페이징을 수행해야 할 때는 일반적으로 임시 테이블도 사용합니다.출력 매개변수를 사용하여 총 레코드 수를 반환할 수 있습니다.Select의 Case 문을 사용하면 동적 SQL을 사용하지 않고도 특정 열의 데이터를 정렬할 수 있습니다.
--Declaration--
--Variables
@StartIndex INT,
@PageSize INT,
@SortColumn VARCHAR(50),
@SortDirection CHAR(3),
@Results INT OUTPUT
--Statements--
SELECT @Results = COUNT(ID) FROM Customers
WHERE FirstName LIKE '%a%'
SET @StartIndex = @StartIndex - 1 --Either do this here or in code, but be consistent
CREATE TABLE #Page(ROW INT IDENTITY(1,1) NOT NULL, id INT, sorting_1 SQL_VARIANT, sorting_2 SQL_VARIANT)
INSERT INTO #Page(ID, sorting_1, sorting_2)
SELECT TOP (@StartIndex + @PageSize)
ID,
CASE
WHEN @SortColumn='FirstName' AND @SortDirection='ASC' THEN CAST(FirstName AS SQL_VARIANT)
WHEN @SortColumn='LastName' AND @SortDirection='ASC' THEN CAST(LastName AS SQL_VARIANT)
ELSE NULL
END AS sort_1,
CASE
WHEN @SortColumn='FirstName' AND @SortDirection='DES' THEN CAST(FirstName AS SQL_VARIANT)
WHEN @SortColumn='LastName' AND @SortDirection='DES' THEN CAST(LastName AS SQL_VARIANT)
ELSE NULL
END AS sort_2
FROM (
SELECT
CustomerId AS ID,
FirstName,
LastName
FROM Customers
WHERE
FirstName LIKE '%a%'
) C
ORDER BY sort_1 ASC, sort_2 DESC, ID ASC;
SELECT
ID,
Customers.FirstName,
Customers.LastName
FROM #Page
INNER JOIN Customers ON
ID = Customers.CustomerId
WHERE ROW > @StartIndex AND ROW <= (@StartIndex + @PageSize)
ORDER BY ROW ASC
DROP TABLE #Page
불행히도 이를 수행하려면 별도의 쿼리를 수행해야 한다고 생각합니다.
이 페이지의 도움을 받아 이전 위치에서 이 작업을 수행할 수 있었습니다.DotNet 2.0의 페이징
또한 행 개수를 별도로 가져옵니다.
페이징을 위해 내가 하는 일은 다음과 같습니다.페이징해야 하는 모든 주요 쿼리는 임시 테이블에 삽입으로 코딩됩니다.임시 테이블에는 위에서 언급한 row_number()와 유사한 방식으로 작동하는 ID 필드가 있습니다.호출 코드가 총 레코드 수를 알 수 있도록 임시 테이블의 행 수를 출력 매개 변수에 저장합니다.호출 코드는 또한 원하는 페이지와 임시 테이블에서 선택되는 페이지당 행 수를 지정합니다.
이 방법의 멋진 점은 보고서의 모든 행을 내 애플리케이션의 모든 그리드 위에 CSV로 반환할 수 있는 "내보내기" 링크도 있다는 것입니다.이 링크는 동일한 저장 프로시저를 사용합니다.페이징 논리를 수행하는 대신 임시 테이블의 내용을 반환하기만 하면 됩니다.이는 페이징을 싫어하고 보고 싶어하는 사용자를 달래줍니다. 모든 것, 수백만 가지 방법으로 정렬하고 싶습니다.