2008-08-05 52 views
36

Làm cách nào để kết quả trang trong SQL Server 2005?Phân trang SQL Server 2005 Kết quả

Tôi đã thử trong SQL Server 2000, nhưng không có cách nào đáng tin cậy để thực hiện việc này. Tôi đang tự hỏi nếu SQL Server 2005 có bất kỳ phương pháp được xây dựng trong?

Điều tôi ngụ ý bằng phân trang là, ví dụ: nếu tôi liệt kê người dùng theo tên người dùng của họ, tôi muốn chỉ có thể trả lại 10 bản ghi đầu tiên, sau đó là 10 bản ghi tiếp theo v.v.

Mọi trợ giúp sẽ được đánh giá cao.

Trả lời

33

Bạn có thể sử dụng chức năng the Row_Number(). của nó sử dụng như sau:

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName 
FROM Users 

Từ đó nó sẽ mang lại một kết quả thiết lập với một lĩnh vực RowID mà bạn có thể sử dụng để trang giữa.

SELECT * 
FROM 
    (SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName 
     FROM Users 
    ) As RowResults 
WHERE RowID Between 5 AND 10 

vv

+0

Tuyệt vời, ví dụ đơn giản Pat - chính xác những gì tôi đã sau :) – Town

+0

Câu trả lời này không hiệu quả đối với tôi, mặc dù nó đã giúp tôi gần gũi hơn. Nó phàn nàn rằng nó không biết RowID là gì. Xem câu trả lời của tôi bên dưới để biết thêm thông tin, nếu bạn có cùng một vấn đề. – Beska

+2

Trong lựa chọn bên trong, bạn có thể chọn các hàng TOP X (X = hàng tối đa muốn, trong trường hợp này - 10). Nó sẽ cải thiện tốc độ truy vấn. – Faruz

0

Tôi tin rằng bạn sẽ cần phải thực hiện một truy vấn riêng biệt để thực hiện điều đó unfortionately.

tôi đã có thể thực hiện điều này ở vị trí trước đây của tôi sử dụng một số sự giúp đỡ từ trang này: Paging in DotNet 2.0

Họ cũng có nó kéo một hàng đếm riêng rẽ.

0

Đây là những gì tôi làm để phân trang: Tất cả các truy vấn lớn của tôi cần được phân trang được mã hóa dưới dạng chèn vào bảng tạm thời. Bảng tạm thời có trường nhận dạng sẽ hoạt động theo cách tương tự với row_number() được đề cập ở trên. Tôi lưu trữ số lượng hàng trong bảng tạm thời trong một tham số đầu ra để mã gọi biết tổng số bản ghi có bao nhiêu. Mã gọi cũng chỉ định trang nào nó muốn và số lượng hàng trên mỗi trang được chọn từ bảng tạm thời.

Điều thú vị khi thực hiện theo cách này là tôi cũng có liên kết "Xuất" cho phép bạn nhận tất cả các hàng từ báo cáo được trả lại dưới dạng CSV phía trên mọi lưới trong ứng dụng của tôi. Liên kết này sử dụng cùng một thủ tục được lưu trữ: bạn chỉ cần trả lại nội dung của bảng tạm thời thay vì làm logic phân trang. Điều này làm cho người dùng khó chịu phân trang và muốn xem mọi thứ và muốn sắp xếp theo một triệu cách khác nhau.

13

Nếu bạn đang cố gắng để có được nó trong một tuyên bố (tổng cộng cộng với phân trang). Bạn có thể cần phải khám phá sự hỗ trợ SQL Server cho phân vùng theo mệnh đề (các hàm cửa sổ trong các thuật ngữ ANSI SQL). Trong Oracle cú pháp giống như ví dụ trên sử dụng row_number(), nhưng tôi cũng đã thêm phân vùng theo mệnh đề để lấy tổng số hàng được bao gồm trong mỗi hàng được trả về trong phân trang (tổng số hàng là 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 

Lưu ý rằng tôi có chủ sở hữu = 'CSEIS' và phân vùng của tôi theo chủ sở hữu. Vì vậy, kết quả là:

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 
+1

+1 Tôi đã tự hỏi làm thế nào để có được tổng số hàng và trang mà không cần sử dụng một bảng tạm thời. Cảm ơn!! – dotjoe

+2

+1 tốt đẹp - làm cho nó hoạt động trên sqlserver bằng cách sử dụng COUNT (*) OVER (PARTITION BY NULL) – Hafthor

+1

+1 ... tốt đẹp. Bây giờ để chơi với nó :-) Bạn có biết về bất kỳ hit hiệu suất sử dụng COUNT (*) OVER (...)? –

2

Khi tôi cần phân trang, tôi thường sử dụng bảng tạm thời. Bạn có thể sử dụng tham số đầu ra để trả về tổng số bản ghi. Các câu lệnh case trong select cho phép bạn sắp xếp dữ liệu trên các cột cụ thể mà không cần phải sử dụng SQL động.

--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 
+3

Đây là những gì bạn sẽ làm trong Sql Server 2000, nhưng phiên bản 2005 có giải pháp tốt hơn khi sử dụng Hàm ROW_NUMBER. – niaher

5

Câu trả lời được chấp nhận cho điều này không thực sự hiệu quả đối với tôi ... Tôi phải nhảy qua một vòng nữa để làm cho nó hoạt động.

Khi tôi cố gắng câu trả lời

SELECT Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName 
FROM Users 
WHERE RowID Between 0 AND 9 

nó thất bại, phàn nàn rằng nó không biết chuyện gì ROWID là.

tôi phải quấn nó trong một bên chọn như thế này:

SELECT * 
FROM 
    (SELECT 
    Row_Number() OVER(ORDER BY UserName) As RowID, UserFirstName, UserLastName 
    FROM Users 
    ) innerSelect 
WHERE RowID Between 0 AND 9 

và sau đó nó làm việc.

Các vấn đề liên quan