Trong PostgreSQL có sự Limit
và Offset
từ khóa mà sẽ cho phép pagination rất dễ dàng của tập kết quả.
Cú pháp tương đương cho SQL Server là gì?
Trong PostgreSQL có sự Limit
và Offset
từ khóa mà sẽ cho phép pagination rất dễ dàng của tập kết quả.
Cú pháp tương đương cho SQL Server là gì?
Câu trả lời:
Tương đương LIMIT
là SET ROWCOUNT
, nhưng nếu bạn muốn pagination chung nó tốt hơn để viết một truy vấn như thế này:
;WITH Results_CTE AS
(
SELECT
Col1, Col2, ...,
ROW_NUMBER() OVER (ORDER BY SortCol1, SortCol2, ...) AS RowNum
FROM Table
WHERE <whatever>
)
SELECT *
FROM Results_CTE
WHERE RowNum >= @Offset
AND RowNum < @Offset + @Limit
Ưu điểm ở đây là tham số hóa của phần bù và giới hạn trong trường hợp bạn quyết định thay đổi tùy chọn phân trang của mình (hoặc cho phép người dùng làm như vậy).
Lưu ý: các @Offset
tham số nên sử dụng một căn cứ lập chỉ mục cho thay này hơn việc lập chỉ mục zero-based bình thường.
WHERE RowNum >= (@Offset + 1)
The ORDER BY clause is invalid in views, inline functions, derived tables, subqueries, and common table expressions, unless TOP or FOR XML is also specified
. MSSQL2008 R2.
Table
có 200k hồ sơ, nó sẽ tìm nạp tất cả trước, sau đó áp dụng giới hạn? Là truy vấn này có hiệu quả?
Tính năng này hiện được thực hiện dễ dàng trong SQL Server 2012. Điều này hoạt động từ SQL Server 2012 trở đi.
Giới hạn với offset để chọn 11 đến 20 hàng trong SQL Server:
SELECT email FROM emailTable
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
OFFSET
: số lượng hàng bị bỏ quaNEXT
: số lượng hàng tiếp theo yêu cầuSQL_CALC_FOUND_ROWS
khi sử dụng này?
select top {LIMIT HERE} * from (
select *, ROW_NUMBER() over (order by {ORDER FIELD}) as r_n_n
from {YOUR TABLES} where {OTHER OPTIONAL FILTERS}
) xx where r_n_n >={OFFSET HERE}
Lưu ý:
Giải pháp này sẽ chỉ hoạt động trong SQL Server 2005 trở lên, vì điều này là khi ROW_NUMBER()
được triển khai.
AS xx
Đối với tôi, việc sử dụng OFFSET và FETCH cùng nhau rất chậm, vì vậy tôi đã sử dụng kết hợp TOP và OFFSET như thế này (nhanh hơn):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Lưu ý: Nếu bạn sử dụng TOP và OFFSET cùng một truy vấn như:
SELECT TOP 20 columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS
Sau đó, bạn gặp lỗi, vì vậy để sử dụng TOP và OFFSET cùng nhau, bạn cần tách nó bằng một truy vấn phụ.
Và nếu bạn cần sử dụng CHỌN DISTINCT thì truy vấn sẽ như sau:
SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
Lưu ý: Việc sử dụng CHỌN ROW_NUMBER với DISTINCT không hiệu quả với tôi.
SELECT TOP 20 id FROM table1 where id > 10 order by date OFFSET 20 rows
, bạn phải chuyển đổi nó như thế nào SELECT TOP 20 * FROM (SELECT id FROM table1 where id > 10 order by date OFFSET 20 ROWS) t1
. Tôi sẽ chỉnh sửa câu trả lời của tôi. Cảm ơn và xin lỗi tiếng Anh của tôi.
Một mẫu khác:
declare @limit int
declare @offset int
set @offset = 2;
set @limit = 20;
declare @count int
declare @idxini int
declare @idxfim int
select @idxfim = @offset * @limit
select @idxini = @idxfim - (@limit-1);
WITH paging AS
(
SELECT
ROW_NUMBER() OVER (order by object_id) AS rowid, *
FROM
sys.objects
)
select *
from
(select COUNT(1) as rowqtd from paging) qtd,
paging
where
rowid between @idxini and @idxfim
order by
rowid;
Có ở đây một ai đó kể về tính năng này trong sql 2011, nó buồn họ chọn một chút từ khóa khác nhau "OFFSET / FETCH" nhưng không phải của nó standart sau đó ok.
Thêm một biến thể nhỏ vào giải pháp của Aaronaught, tôi thường tham số số trang (@PageNum) và kích thước trang (@PageSize). Bằng cách này, mỗi sự kiện nhấp vào trang chỉ gửi số trang được yêu cầu cùng với kích thước trang có thể định cấu hình:
begin
with My_CTE as
(
SELECT col1,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
select * from My_CTE
WHERE RowNum BETWEEN (@PageNum - 1) * (@PageSize + 1)
AND @PageNum * @PageSize
end
Gần nhất tôi có thể làm là
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
Mà tôi đoán tương tự như select * from [db].[dbo].[table] LIMIT 0, 10
@nombre_row :nombre ligne par page
@page:numero de la page
//--------------code sql---------------
declare @page int,@nombre_row int;
set @page='2';
set @nombre_row=5;
SELECT *
FROM ( SELECT ROW_NUMBER() OVER ( ORDER BY etudiant_ID ) AS RowNum, *
FROM etudiant
) AS RowConstrainedResult
WHERE RowNum >= ((@page-1)*@nombre_row)+1
AND RowNum < ((@page)*@nombre_row)+1
ORDER BY RowNum
Vì chưa ai cung cấp mã này:
SELECT TOP @limit f1, f2, f3...
FROM t1
WHERE c1 = v1, c2 > v2...
AND
t1.id NOT IN
(SELECT TOP @offset id
FROM t1
WHERE c1 = v1, c2 > v2...
ORDER BY o1, o2...)
ORDER BY o1, o2...
Điểm quan trọng:
@limit
có thể được thay thế bằng số lượng kết quả để lấy,@offset
là số kết quả cần bỏ quawhere
và order by
mệnh đề và sẽ cung cấp kết quả không chính xác nếu chúng không đồng bộorder by
là có rõ ràng nếu đó là những gì cần thiếtCụ thể cho SQL-SERVER, bạn có thể đạt được điều đó theo nhiều cách khác nhau. Ví dụ thực tế, chúng tôi đã lấy bảng Khách hàng tại đây.
Ví dụ 1: Với "SET ROWCOUNT"
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Để trả về tất cả các hàng, đặt ROWCOUNT thành 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
Ví dụ 2: Với "ROW_NUMBER và QUÁ"
With Cust AS
( SELECT CustomerID, CompanyName,
ROW_NUMBER() OVER (order by CompanyName) as RowNumber
FROM Customers )
select *
from Cust
Where RowNumber Between 0 and 10
Ví dụ 3: Với "OFFSET và FETCH", nhưng với "ORDER BY" này là bắt buộc
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
Hy vọng điều này sẽ giúp bạn.
Vì, tôi đã kiểm tra tập lệnh này nhiều lần hơn, hữu ích hơn 1 triệu bản ghi mỗi trang 100 bản ghi với phân trang hoạt động nhanh hơn PC của tôi thực thi tập lệnh này 0 giây trong khi so sánh với mysql có giới hạn riêng và bù khoảng 4,5 giây để có kết quả.
Ai đó có thể bỏ lỡ việc hiểu Row_Number () luôn sắp xếp theo trường cụ thể. Trong trường hợp chúng ta chỉ cần xác định hàng theo thứ tự nên sử dụng:
SELECT TOP {LIMIT} * FROM (
SELECT TOP {LIMIT} + {OFFSET} ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS ROW_NO,*
FROM {TABLE_NAME}
) XX WHERE ROW_NO > {OFFSET}
Giải thích: