2012-11-04 29 views
72

Tôi đã cố gắng hiểu một chút về cách triển khai phân trang tùy chỉnh trong SQL, ví dụ: đọc articles like this one.Thực hiện chức năng phân trang (bỏ qua/lấy) với truy vấn này

Tôi có truy vấn sau, hoạt động hoàn hảo. Nhưng tôi muốn thực hiện phân trang với cái này.

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

gì là nó Tôi muốn

Tôi có bài viết diễn đàn, với mục có liên quan. Tôi muốn nhận các bài đăng có các mục nhập mới nhất, vì vậy tôi có thể chọn các bài đăng được tranh luận gần đây.

Bây giờ, tôi muốn có thể nhận được "10 đến 20 bài đăng hoạt động gần đây nhất", thay vì "top 10".

có gì tôi đã cố gắng

Tôi đã cố gắng để thực hiện các chức năng ROW là một trong bài viết, nhưng thực sự không có may mắn.

Bất kỳ ý tưởng nào về cách triển khai?

Trả lời

161

Trong SQL Server 2012 nó là rất rất dễ

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 

Nếu chúng ta muốn bỏ qua ORDER BY chúng ta có thể sử dụng

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

(Tôi thà đánh dấu đó như một hack - nhưng nó được sử dụng, ví dụ như NHibernate. Để sử dụng cột được chọn một cách khôn ngoan như ORDER BY là cách ưa thích)

to trả lời các câu hỏi:

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

từ khóa mới offsetfetch next (chỉ theo tiêu chuẩn SQL) đã được giới thiệu.

Nhưng tôi đoán rằng bạn không sử dụng SQL Server 2012, phải? Trong phiên bản trước nó là một chút (chút) khó khăn. Dưới đây là so sánh và ví dụ cho tất cả các phiên bản SQL server: here

Vì vậy, điều này có thể làm việc trong 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 
+0

Cảm ơn rất nhiều! Đó là một câu trả lời thực sự tốt! Chỉ câu hỏi về sql 2008. Tôi muốn ORDER BY xảy ra trước WHERE, vì nó hiện đang sắp xếp tập hợp con, nhưng chúng tôi muốn chọn thứ gì đó từ toàn bộ ... Bất kỳ ý tưởng nào? :) Một lần nữa, cảm ơn –

+2

Nếu tôi hiểu chính xác bạn, bạn muốn sắp xếp theo LastDate, phải không? sau đó chúng ta có thể thay đổi mệnh đề OVER() theo cách này: ROW_NUMBER() OVER (ORDER BY ** MAX (Datemade) desc **). * Và loại bỏ ORDER cuối cùng bởi PostId *. Bây giờ CTE nên được sắp xếp 'sớm hơn' khi cần thiết. chính xác? –

+1

Cảm ơn bạn điều này đã giúp, một lưu ý về mẫu 2012, thứ tự là bắt buộc, tôi đã thử điều này mà không cần mệnh lệnh và có lỗi "cú pháp sai" không biết có gì sai cho đến khi tôi nhìn vào cú pháp MSDN và biết thứ tự đó là bắt buộc. – Esen

4

Để làm điều này trong SQL Server, bạn phải ra lệnh truy vấn bằng cách một cột, vì vậy bạn có thể chỉ định các hàng bạn muốn.

Ví dụ:

select * from table order by [some_column] 
offset 10 rows 
FETCH NEXT 10 rows only 

Và bạn không thể sử dụng "TOP" từ khóa khi làm điều này.

Bạn có thể tìm hiểu thêm ở đây: https://technet.microsoft.com/pt-br/library/gg699618%28v=sql.110%29.aspx

1
OFFSET  10 ROWS  -- skip 10 rows 
FETCH NEXT 10 ROWS ONLY; -- take 10 rows 

sử dụng này vào cuối cú pháp chọn của bạn. =)

3

SQL 2008 công trình câu trả lời

Radim Köhler, nhưng đây là một phiên bản ngắn hơn:

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

Nguồn: https://forums.asp.net/post/4033909.aspx

0

Bạn có thể sử dụng truy vấn lồng nhau cho pagination như sau: Phân trang từ 4 Hàng đến 8 Hàng trong đó CustomerId là khóa chính

SELECT Top 5 * FROM Customers WHERE Country = 'Germany' VÀ CustomerId Không ở trong (SELECT Top 3 CustomerID TỪ Khách hàng WHERE Country = 'Đức' theo thành phố) đặt hàng theo thành phố;

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