ใน PostgreSQL มีLimit
และOffset
คำหลักซึ่งจะช่วยให้การแบ่งหน้าง่ายของชุดผลลัพธ์
ไวยากรณ์เทียบเท่าสำหรับ SQL Server คืออะไร
ใน PostgreSQL มีLimit
และOffset
คำหลักซึ่งจะช่วยให้การแบ่งหน้าง่ายของชุดผลลัพธ์
ไวยากรณ์เทียบเท่าสำหรับ SQL Server คืออะไร
คำตอบ:
เทียบเท่าLIMIT
คือSET ROWCOUNT
แต่ถ้าคุณต้องการเลขหน้าทั่วไปมันจะดีกว่าถ้าเขียนเคียวรีดังนี้
;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
ข้อได้เปรียบที่นี่คือการกำหนดพารามิเตอร์ของออฟเซ็ตและ จำกัด ในกรณีที่คุณตัดสินใจที่จะเปลี่ยนตัวเลือกการเพจ (หรืออนุญาตให้ผู้ใช้ทำ)
หมายเหตุ:@Offset
พารามิเตอร์ควรใช้การจัดทำดัชนีหนึ่งที่ใช้สำหรับการนี้มากกว่าปกติการจัดทำดัชนี zero-based
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
มีประวัติ 200k มันจะดึงทั้งหมดมาก่อน แบบสอบถามนี้มีประสิทธิภาพหรือไม่
ฟีเจอร์นี้ทำให้ง่ายใน SQL Server 2012 ซึ่งทำงานจาก SQL Server 2012 เป็นต้นไป
จำกัด ด้วย offset เพื่อเลือก 11 ถึง 20 แถวใน SQL Server:
SELECT email FROM emailTable
WHERE user_id=3
ORDER BY Id
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY;
OFFSET
: จำนวนแถวที่ข้ามNEXT
: จำนวนแถวถัดไปที่ต้องการการอ้างอิง: https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-2017
SQL_CALC_FOUND_ROWS
ใช้งานเท่ากันเมื่อใช้สิ่งนี้?
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}
หมายเหตุ:
วิธีนี้จะใช้ได้เฉพาะใน SQL Server 2005 หรือใหม่กว่าROW_NUMBER()
เท่านั้น
AS xx
คุณสามารถใช้ ROW_NUMBER ใน Common Table Expression เพื่อทำสิ่งนี้
;WITH My_CTE AS
(
SELECT
col1,
col2,
ROW_NUMBER() OVER(ORDER BY col1) AS row_number
FROM
My_Table
WHERE
<<<whatever>>>
)
SELECT
col1,
col2
FROM
My_CTE
WHERE
row_number BETWEEN @start_row AND @end_row
สำหรับฉันการใช้ OFFSET และ FETCH ร่วมกันนั้นช้าดังนั้นฉันจึงใช้การรวมกันของ TOP และ OFFSET เช่นนี้ (ซึ่งเร็วกว่า):
SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
หมายเหตุ:หากคุณใช้ TOP และ OFFSET ร่วมกันในแบบสอบถามเดียวกันเช่น:
SELECT TOP 20 columname1, columname2 FROM tablename
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS
จากนั้นคุณจะได้รับข้อผิดพลาดดังนั้นสำหรับการใช้ TOP และ OFFSET คุณต้องแยกมันออกด้วยแบบสอบถามย่อย
และถ้าคุณต้องการใช้ SELECT DISTINCT เคียวรีจะเป็นดังนี้:
SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname
หมายเหตุ:การใช้ SELECT ROW_NUMBER กับ DISTINCT ไม่ได้ผลสำหรับฉัน
SELECT TOP 20 id FROM table1 where id > 10 order by date OFFSET 20 rows
SELECT TOP 20 * FROM (SELECT id FROM table1 where id > 10 order by date OFFSET 20 ROWS) t1
ฉันจะแก้ไขคำตอบของฉัน ขอบคุณและขอโทษด้วยภาษาอังกฤษของฉัน
ตัวอย่างอื่น:
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;
นอกจากนี้ที่นี่มีคนบอกเกี่ยวกับคุณลักษณะนี้ใน SQL 2011 มันน่าเศร้าที่พวกเขาเลือกคำหลักที่แตกต่างกันเล็ก ๆ น้อย ๆ "OFFSET / เรียก" แต่ไม่ได้มาตรฐาน ok แล้วมัน
การเพิ่มความแตกต่างเล็กน้อยในการแก้ปัญหาของ Aaronaught ฉันมักจะ parametrize หมายเลขหน้า (@PageNum) และขนาดหน้า (@PageSize) วิธีนี้แต่ละเหตุการณ์การคลิกหน้าเพียงแค่ส่งหมายเลขหน้าที่ร้องขอพร้อมกับขนาดหน้าที่กำหนดค่าได้:
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
สิ่งที่ฉันสามารถทำได้ใกล้เคียงที่สุดคือ
select * FROM( SELECT *, ROW_NUMBER() over (ORDER BY ID ) as ct from [db].[dbo].[table] ) sub where ct > fromNumber and ct <= toNumber
ซึ่งฉันเดาว่าคล้ายกับ select * from [db].[dbo].[table] LIMIT 0, 10
select top (@TakeCount) * --FETCH NEXT
from(
Select ROW_NUMBER() OVER (order by StartDate) AS rowid,*
From YourTable
)A
where Rowid>@SkipCount --OFFSET
@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
เนื่องจากยังไม่มีใครให้รหัสนี้:
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...
จุดสำคัญ:
@limit
สามารถแทนที่ด้วยจำนวนผลลัพธ์ที่จะเรียกคืนได้@offset
คือจำนวนผลลัพธ์ที่จะข้ามwhere
และส่วนorder by
คำสั่งและจะให้ผลลัพธ์ที่ไม่ถูกต้องหากไม่มีการซิงค์order by
หากมีสิ่งที่ต้องการอย่างชัดเจน-- @RowsPerPage can be a fixed number and @PageNumber number can be passed
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 2
SELECT *
FROM MemberEmployeeData
ORDER BY EmployeeNumber
OFFSET @PageNumber*@RowsPerPage ROWS
FETCH NEXT 10 ROWS ONLY
โดยเฉพาะสำหรับ SQL-SERVER คุณสามารถทำสิ่งนั้นได้หลายวิธีตัวอย่างที่แท้จริงเรานำตารางลูกค้ามาที่นี่
ตัวอย่างที่ 1: ด้วย "SET ROWCOUNT"
SET ROWCOUNT 10
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
หากต้องการส่งคืนแถวทั้งหมดให้ตั้ง ROWCOUNT เป็น 0
SET ROWCOUNT 0
SELECT CustomerID, CompanyName from Customers
ORDER BY CompanyName
ตัวอย่างที่ 2: ด้วย "ROW_NUMBER และ OVER"
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
ตัวอย่างที่ 3: ด้วย "OFFSET และ FETCH" แต่ด้วย "ORDER BY" นี้เป็นสิ่งจำเป็น
SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY
หวังว่านี่จะช่วยคุณได้
ใน SQL server คุณจะใช้ TOP พร้อมกับ ROW_NUMBER ()
ตั้งแต่ฉันทดสอบมากกว่านี้สคริปต์นี้มีประโยชน์มากกว่า 1 ล้านบันทึกในแต่ละหน้า 100 บันทึกด้วยการให้เลขหน้าเร็วขึ้นพีซีของฉันใช้สคริปต์นี้ 0 วินาทีในขณะที่เปรียบเทียบกับ mysql มีข้อ จำกัด ของตัวเองและชดเชยประมาณ 4.5 วินาทีเพื่อให้ได้ผลลัพธ์
บางคนอาจพลาดการเข้าใจ Row_Number () เรียงลำดับตามฟิลด์ที่ระบุเสมอ ในกรณีที่เราจำเป็นต้องกำหนดแถวตามลำดับเท่านั้นควรใช้:
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}
อธิบาย: