এসকিউএল সার্ভারের জন্য সীমাবদ্ধ এবং অফসেটের সমতুল্য?


172

PostgreSQL এ রয়েছে Limit এবং Offsetকিওয়ার্ড যা ফলাফলের সেট খুব সহজ পত্রাঙ্কন অনুমতি দেবে।

এসকিউএল সার্ভারের সমতুল্য বাক্য গঠন কী?


SQL সার্ভার 2012 এর জন্য, এই বৈশিষ্ট্যটি সহজ উপায়ে প্রয়োগ করা হয়েছে। আমার উত্তর
সোমনাথ মুলুক

এই প্রশ্নটি জিজ্ঞাসা করার জন্য ধন্যবাদ, আমরা মাইএসকিউএল থেকে এমএসএসকিউএল রূপান্তর করতে বাধ্য হচ্ছি :(
টেম্পেক

আপনি অফসেট ব্যবহার করতে পারেন এবং এসকিউএল সার্ভারে ধারা দ্বারা আদেশ সহ পরবর্তী বিবৃতি আনতে পারেন। এটি চেষ্টা করুন youtu.be/EqHkAiBwPc
অমরেশ কুমার সিংহ

উত্তর:


139

সমতুল্য 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 পরামিতি স্বাভাবিক শূন্য ভিত্তিক ইন্ডেক্স চেয়ে বরং এক-ভিত্তিক ইন্ডেক্স ব্যবহার করা উচিত।


22
এখন পুরানো। এসকিএল সার্ভার ২০১২ এবং
তারপরে অফসেট

31
পুনঃটুইট আমি কেবল এসএলকিউ সার্ভার ২০০৮ ব্যবহার করে প্রজেক্টে বরাদ্দ পেয়েছি কেবল অতীতে কেবল মাইএসকিএল ব্যবহার করে ...
চিতুলহু

এটি বেশ ভাল তবে কিছুটা সামঞ্জস্য করা দরকারWHERE RowNum >= (@Offset + 1)
এরিক হার্লিটজ

5
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। এমএসএসকিউএল ২০০৮ আর 2।
পল

2
@ অ্যারোনট যদি আমার Table200k রেকর্ড থাকে তবে এটি প্রথমে সমস্তটি নিয়ে আসে, তারপরে সীমাটি প্রয়োগ করবেন? এই কোয়েরি দক্ষ?
জিগার

231

এই বৈশিষ্ট্যটি এখন এসকিউএল সার্ভার ২০১২-তে সহজ করা হয়েছে S এটি এসকিউএল সার্ভার ২০১২ থেকে কাজ করছে।

এসকিউএল সার্ভারে 11 থেকে 20 টি সারি নির্বাচন করতে অফসেট সহ সীমাবদ্ধ করুন:

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


4
এটি SQL_CALC_FOUND_ROWSব্যবহার করার সময় কি কোনও সমতুল্য থাকে ?
পেটাঃ

1
@ পেটা @@ রওকাউন্ট আপনাকে দিবে যা আমি মনে করি
রব সেডগউইক

গোটচা: আপনি এটি কোনও সিটিইর মধ্যে থেকে ব্যবহার করতে পারবেন না। এটি মূল ক্যোয়ারিতে ব্যবহার করতে হবে। আমি ফিরে আসা সারির পরিমাণ সীমাবদ্ধ করতে চেয়েছিলাম (পৃষ্ঠাগুলি) এবং তারপরে সারিগুলি নির্ধারণ করার পরিবর্তে ব্যয়বহুল গণনা সম্পাদন করার পরিবর্তে 10 বা ততোধিক সারি ফিরে আসার জন্য একটি ব্যয়বহুল গণনা সম্পাদন করতে এবং তারপরে / আমার প্রয়োজনীয় জিনিসগুলি এড়িয়ে / নিয়ে যেতে চেয়েছিলাম। @ হার্টনউটের উত্তর তাদের জন্য কাজ করবে যারা একটি সিটিইর মধ্যে সারি সীমাবদ্ধ রাখে।
ডেরেক ডিন

@ সোমনাথ মুলুক এই অফসেট এবং আনতে 1000000 অফসেট সহ ডেটা উদাহরণের উচ্চতর ভলিউমের জন্য অনেক সময় নিচ্ছে this আমি কীভাবে এটি মোকাবেলা করতে পারি?
সরোজ শ্রেষ্ঠ 11

1
@ সরোজশ্রেষ্ঠ: এটি অফসেট এবং আনার বিষয়টি নয়। আপনার এখন আপনার টেবিলের আর্কিটেকচারটি ঘুরে দেখা উচিত। টেবিলগুলির বিভাজন, আপনার ডেটা সারি এবং এটি বিভিন্ন কলামের ধরণ এবং মোট টেবিলের আকার বিবেচনা করুন, নিয়মিত প্রয়োজন না হলে কিছু সারি সংরক্ষণাগার বিবেচনা করুন, আপনার সার্ভারের চশমাটি পরীক্ষা করুন check
সোমনাথ মুলুক

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

একটি দ্রষ্টব্য: এই সমাধানটি কেবল এসকিউএল সার্ভার ২০০৫ বা তারপরেই কাজ করবে, যেহেতু ROW_NUMBER()এটি কার্যকর হয়েছিল তখন ।


আমি এই ক্যোয়ারীটি অল্প সময়ের জন্য ব্যবহার করছি এবং এটি দুর্দান্ত কাজ করে তাই এর জন্য ধন্যবাদ। আমি শুধু ভাবছি যে 'এক্সএক্স' প্রতিনিধিত্ব করে?
উর্বলি

সাব ক্যোয়ারির একটি নাম প্রয়োজন। যেহেতু আমি এটি ব্যবহার করছি না সেখানে কেবল xx
রেখেছি

2
এক্সএক্সটি কেবল একটি টেবিল ওরফে। আপনি যদি বলেন তবে এটি আরও পরিষ্কার হতে পারেAS xx
কংক্রিট গ্যানেট

এই কোয়েরিতে কীভাবে বামে যোগ দিতে হয় কেউ জানেন?
ড্রেনাইল

12

এটি অর্জনের জন্য আপনি একটি সাধারণ টেবিল এক্সপ্রেশনটিতে 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

4

আমার জন্য অফসেট এবং ফিটের একসাথে ব্যবহার ধীর ছিল, তাই আমি এই জাতীয় শীর্ষ এবং অফসেটের সংমিশ্রণটি ব্যবহার করেছি (যা দ্রুত ছিল):

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

দ্রষ্টব্য: আপনি যদি একই ওপরে টপ এবং অফসেট একসাথে ব্যবহার করেন তবে:

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

তারপরে আপনি একটি ত্রুটি পান, সুতরাং শীর্ষ এবং অফসফট একসাথে ব্যবহারের জন্য আপনাকে এটিকে একটি সাব-কোয়েরির সাথে পৃথক করতে হবে।

এবং যদি আপনার SELECT DISTINCT ব্যবহার করতে হয় তবে ক্যোয়ারীটি এমন:

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

দ্রষ্টব্য: DISTINCT সহ SELECT ROW_NUMBER এর ব্যবহার আমার পক্ষে কার্যকর হয়নি।


1
আমি পেয়েছি "একটি শীর্ষস্থানীয় অফার হিসাবে একই ক্যোয়ারী বা সাব-কোয়েরিতে ব্যবহার করা যাবে না।"
মাইকেলরশটন

আপনি ঠিক @ মিশেল রুশটন, একই ক্যোয়ারিতে বা একই উপ-কোয়েরিতে ব্যবহার করা যাবে না, তারপরে আপনাকে আলাদা করতে একটি সাব-কোয়েরি ব্যবহার করতে হবে। সুতরাং আপনার যদি এসকিউএল পছন্দ হয় তবে 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। আমি আমার উত্তর সম্পাদনা করব। ধন্যবাদ এবং আমাকে আমার ইংরেজি ক্ষমা করুন।
সেবাসদেব

2

আরেকটি নমুনা:

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;

15
আমি আপনার অ্যান্টি-মাইক্রোসফ্ট ঘৃণাত্মক বক্তৃতা সরিয়েছি। পবিত্র যুদ্ধসমূহ এখানে আলোচনা করবেন না; একটি উত্তর-বিষয়হীন উপায়ে কেবল উত্তর দিন এবং প্রশ্ন জিজ্ঞাসা করুন।
আর্লজ

2

নেই এখানে SQL 2011 সালে এই বৈশিষ্ট্যটি, তার দু: খিত তারা একটু ভিন্ন শব্দ চয়ন "OFFSET / আনা" কিন্তু তার, standart তারপর ঠিক নয় সম্পর্কে কেউ বলার।


2

অ্যারোনআউট এর সমাধানটিতে সামান্যতম প্রকরণ যুক্ত করে আমি সাধারণত পৃষ্ঠা নম্বর (@ পেজনাম) এবং পৃষ্ঠার আকার (@ পেজসাইজ) প্যারাম্যাট্রাইজ করি। প্রতিটি পৃষ্ঠার ক্লিক ইভেন্টটি একটি কনফিগারযোগ্য পৃষ্ঠা আকারের সাথে অনুরোধ করা পৃষ্ঠা নম্বরটিতে কেবল প্রেরণ করে:

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

2

সবচেয়ে কাছেরটা আমি করতে পারি

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


1
select top (@TakeCount) * --FETCH NEXT
from(
    Select  ROW_NUMBER() OVER (order by StartDate) AS rowid,*
    From YourTable
)A
where Rowid>@SkipCount --OFFSET

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

1

যেহেতু কেউ এখনও এই কোডটি সরবরাহ করেনি:

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স্পষ্টভাবে আছে যদি এটির প্রয়োজন হয়

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

1

বিশেষত এসকিউএল-সার্ভারের জন্য আপনি এটি বিভিন্ন উপায়ে অর্জন করতে পারেন given প্রকৃত উদাহরণ হিসাবে আমরা গ্রাহক টেবিলটি এখানে নিয়েছি।

উদাহরণ 1: "সেট 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 এবং ওভার" সহ

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: "অফসেট এবং ফিচার" সহ, তবে এই "অর্ডার বাই" দিয়ে বাধ্যতামূলক

SELECT CustomerID, CompanyName FROM Customers
ORDER BY CompanyName
OFFSET 0 ROWS
FETCH NEXT 10 ROWS ONLY

আশা করি এটি আপনাকে সহায়তা করবে।


-1

এসকিউএল সার্ভারে আপনি শীর্ষগুলি ROW_NUMBER () এর সাথে একসাথে ব্যবহার করবেন


-1

যেহেতু, আমি এই স্ক্রিপ্টটি আরও বার বার পরীক্ষা করে দেখি 1 মিলিয়ন রেকর্ড প্রতিটি পৃষ্ঠার 100 পৃষ্ঠা রেকর্ডিং কাজ করে দ্রুত আমার পিসি এই স্ক্রিপ্ট 0 সেকেন্ড চালায় তবে মাইএসকিএল এর সাথে তুলনা করার নিজস্ব সীমা থাকে এবং ফলাফলটি পেতে প্রায় 4.5 সেকেন্ড অফসেট করে।

কেউ Row_Number () বোঝার জন্য সর্বদা নির্দিষ্ট ক্ষেত্র অনুসারে বাছাই করতে পারে। সিক্যুয়ালে কেবলমাত্র সারিটি সংজ্ঞায়িত করার প্রয়োজন থাকলে ব্যবহার করা উচিত:

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}

ব্যাখ্যা করা:

  • {সীমাবদ্ধতা: প্রতিটি পৃষ্ঠার জন্য রেকর্ডের সংখ্যা
  • F অফসেট}: এড়িয়ে যাওয়া রেকর্ডের সংখ্যা

2
এই কোডটি কীভাবে এবং কেন এই সমস্যার সমাধান করে তার ব্যাখ্যা সহ প্রশ্নটি সমাধান করতে পারে যদিও আপনার পোস্টের গুণমান উন্নত করতে সত্যই সহায়তা করবে এবং সম্ভবত আরও বেশি ভোটের ফলাফল হবে। মনে রাখবেন যে আপনি ভবিষ্যতে পাঠকদের জন্য প্রশ্নের উত্তর দিচ্ছেন, কেবল এখনই জিজ্ঞাসা করা ব্যক্তি নয়। দয়া করে সম্পাদনা ব্যাখ্যা যোগ করতে পারেন এবং সীমাবদ্ধতা এবং অনুমানের কি প্রয়োগ একটি ইঙ্গিত দিতে আপনার উত্তর।
ব্রায়ান
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.