سؤال

في postgresql هناك Limit و Offset الكلمات الرئيسية التي ستسمح بترقيم مجموعات النتائج السهلة للغاية.

ما هو بناء الجملة المكافئ لخادم SQL؟

هل كانت مفيدة؟

المحلول

أي ما يعادل 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 يجب أن تستخدم المعلمة فهرسة واحدة لهذا بدلاً من الفهرسة المعتادة على الصفر.

نصائح أخرى

أصبحت هذه الميزة سهلة الآن في SQL Server 2012. هذا يعمل من SQL Server 2012 فصاعدًا.

الحد من الإزاحة لتحديد 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-plause-transact-sql؟view=sql-server-2017

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() تم تنفيذه.

يمكنك استخدام row_number في تعبير جدول مشترك لتحقيق ذلك.

;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

بالنسبة لي ، كان استخدام الإزاحة وجلبه بطيئًا ، لذلك استخدمت مزيجًا من أعلى وإزاحة مثل هذا (الذي كان أسرع):

SELECT TOP 20 * FROM (SELECT columname1, columname2 FROM tablename
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname

ملحوظة: إذا كنت تستخدم Top and Offset معًا في نفس الاستعلام مثل:

SELECT TOP 20 columname1, columname2 FROM tablename
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS

ثم تحصل على خطأ ، لذا لاستخدام Top and Offset معًا ، تحتاج إلى فصله بالمساعاة الفرعية.

وإذا كنت بحاجة إلى استخدام SELECT DISTER ، فإن الاستعلام يشبه:

SELECT TOP 20 FROM (SELECT DISTINCT columname1, columname2
    WHERE <conditions...> ORDER BY columname1 OFFSET 100 ROWS) aliasname

ملحوظة: استخدام select Row_number مع متميز لم ينجح بالنسبة لي.

عينة أخرى:

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 ، من المحزن أن يختاروا كلمة رئيسية مختلفة قليلاً "الإزاحة / الجلب" ولكنها ليست Standart ثم حسنًا.

إضافة تباين طفيف في حل Aaronaught ، عادةً ما أقوم بتصوير رقم الصفحة (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 ، يمكنك استخدام TOP مع ROW_Number ()

SELECT * FROM [dbo].[TableName] Order By  [dbo].[TableName].FieldName DESC
OFFSET 10 ROWS
FETCH NEXT 10 ROWS ONLY
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top