এসকিউএল সার্ভারে সারি অফসেট


133

এসকিউএল সার্ভারে কোনও প্রদত্ত অফসেটে ফলাফল পেতে কোনও উপায় আছে? উদাহরণস্বরূপ, অন্য ধরণের এসকিউএল ডাটাবেসে, এটি করা সম্ভব:

SELECT * FROM MyTable OFFSET 50 LIMIT 25

51-75 ফলাফল পেতে। এই নির্মাণটি এসকিউএল সার্ভারে উপস্থিত রয়েছে বলে মনে হয় না।

আমার যত্ন নেই এমন সমস্ত সারি লোড না করে কীভাবে আমি এটি সম্পাদন করতে পারি? ধন্যবাদ!


আপনি অফসেট ব্যবহার করতে পারেন এবং পরবর্তী বিবৃতি আনতে পারেন। youtu.be/EqHkAiiBwPc
অমরেশ কুমার সিংহ

উত্তর:


152

আমি ব্যবহার এড়ানো হবে SELECT *। আপনি যে কলামগুলি চান সেগুলি সুনির্দিষ্টভাবে উল্লেখ করুন যদিও সেগুলি সমস্তই হতে পারে।

এসকিউএল সার্ভার 2005+

SELECT col1, col2 
FROM (
    SELECT col1, col2, ROW_NUMBER() OVER (ORDER BY ID) AS RowNum
    FROM MyTable
) AS MyDerivedTable
WHERE MyDerivedTable.RowNum BETWEEN @startRow AND @endRow

এসকিউএল সার্ভার 2000

এসকিউএল সার্ভার 2000-এ বড় ফলাফলের সেটগুলির মাধ্যমে দক্ষতার সাথে পেজিং করা

বড় ফলাফলের ফলাফলগুলির মাধ্যমে পেজিংয়ের জন্য আরও কার্যকর পদ্ধতি


6
আপনি সমস্ত কলাম নির্বাচন করলেও আপনি কেন নির্বাচন এড়ানো পরামর্শ দিচ্ছেন?
অ্যাডাম নেস

12
আমি নিশ্চিত যে তিনি "*" ব্যবহার করেছেন কারণ এটি টাইপ করা সহজ ছিল এবং "কল 1, কল 2, ... কলএন" এর চেয়ে ভাল পয়েন্টটি পেয়েছিল
গিলনবা

9
কেন এটি ব্যবহার করবেন না, তার SELECT *অর্থ এই যে যদি টেবিলের কাঠামো পরিবর্তন হয় তবে আপনার ক্যোয়ারীটি এখনও চলতে থাকে তবে বিভিন্ন ফলাফল দেয়। যদি কোনও কলাম যুক্ত করা হয় তবে এটি কার্যকর হতে পারে (যদিও আপনি এখনও এটি কোথাও নামে ব্যবহার করতে পেরেছেন); যদি কোনও কলাম মুছে ফেলা হয় বা নাম বদলানো হয়, আপনার এসকিউএল এর পক্ষে কোডটি আরও অদ্ভুত আচরণ করার চেয়ে দৃশ্যমানভাবে ভাঙ্গা ভাল because
আইএমএসওপি

5
টেবিল এবং কাটা সব তথ্য নির্বাচন করুন? যদি 5000000000 সারি থাকে? 5000000000 সারি নির্বাচন করুন এবং প্রতিটি প্রশ্নের জন্য কাটা? এটি সিপিইউ এবং সার্ভারের মেমরির জন্য কার্যকর নয়।
ই তথ্য 128

3
দয়া করে মনে রাখবেন যে 2012+ এটি আরও ভালভাবে কার্যকর করেছে। + মার্টিন স্মিথের উত্তর দেখুন
মেরিডিয়াস

100

আপনি যদি সমস্ত পৃষ্ঠাগুলি ক্রমক্রমে প্রক্রিয়াজাতকরণ করে থাকেন তবে কেবল পূর্ববর্তী পৃষ্ঠায় দেখা শেষ কী মানটি স্মরণ করা এবং TOP (25) ... WHERE Key > @last_key ORDER BY Keyযদি উপযুক্ত সূচকগুলি দক্ষতার সাথে অনুসন্ধান করার অনুমতি দেওয়ার জন্য উপস্থিত থাকে তবে ব্যবহার করা সেরা পারফরম্যান্স পদ্ধতি হতে পারে - বা যদি কোনও API কার্সার না করে তবে ।

একটি সালিসি পৃষ্ঠা নির্বাচনের জন্য এসকিউএল সার্ভার 2005 - 2008 আর 2 এর সেরা সমাধান সম্ভবত ROW_NUMBERএবং হয়BETWEEN

এসকিউএল সার্ভার ২০১২+ এর জন্য আপনি এই প্রয়োজনের জন্য বর্ধিত অর্ডার ব্যবহার করতে পারেন ।

SELECT  *
FROM     MyTable 
ORDER BY OrderingColumn ASC 
OFFSET  50 ROWS 
FETCH NEXT 25 ROWS ONLY 

যদিও এই অপশনটি কতটা ভালভাবে সম্পাদন করা হবে তা এখনও দেখার বিষয়


2
এটা তোলে SQL সার্ভার কম্প্যাক্ট এখন পাওয়া যাচ্ছে তা 4.0 -> msdn.microsoft.com/en-us/library/gg699618(v=sql.110).aspx
বার্ট Verkoeijen

13
তারা এটিকে টিএসকিউএলে যুক্ত করার প্রায় সময়
জনএফএক্স

3
কেবলমাত্র
এসকিএল

22

এটি একটি উপায় (এসকিউএল 2000)

SELECT * FROM
(
    SELECT TOP (@pageSize) * FROM
    (
        SELECT TOP (@pageNumber * @pageSize) *
        FROM tableName 
        ORDER BY columnName ASC
    ) AS t1 
    ORDER BY columnName DESC
) AS t2 
ORDER BY columnName ASC

এবং এটি অন্য উপায় (এসকিউএল 2005)

;WITH results AS (
    SELECT 
        rowNo = ROW_NUMBER() OVER( ORDER BY columnName ASC )
        , *
    FROM tableName 
) 
SELECT * 
FROM results
WHERE rowNo between (@pageNumber-1)*@pageSize+1 and @pageNumber*@pageSize

প্রথমটির উপর কেবল স্পষ্ট করার জন্য ... (@ পেজ সাইজ) প্রকৃত মানটির জন্য এখানে স্থানধারক। আপনাকে বিশেষভাবে 'শীর্ষ 25' করতে হবে; এসকিউএল সার্ভার 2000 কোনও শীর্ষ দফায় ভেরিয়েবল সমর্থন করে না। এটি গতিশীল এসকিউএল জড়িত একটি ব্যথা করে তোলে।
কাউয়ান

5
এসকিউএল 2000 এর জন্য যে সমাধানটি ফলাফলের সেটে শেষ পৃষ্ঠার জন্য কাজ করে না, যদি না পাতার মোট সংখ্যাটি পৃষ্ঠার আকারের একাধিক হয়ে থাকে।
বিল কারভিন 18

10

আপনি ROW_NUMBER()যা চান তা পেতে আপনি ফাংশনটি ব্যবহার করতে পারেন:

SELECT *
FROM (SELECT ROW_NUMBER() OVER(ORDER BY id) RowNr, id FROM tbl) t
WHERE RowNr BETWEEN 10 AND 20

7

নেই OFFSET .. FETCHSQL সার্ভার 2012 সালে, তবে আপনি একটি নির্দিষ্ট করার প্রয়োজন হবে ORDER BYকলাম।

আপনার যদি সত্যই কোনও স্পষ্ট কলাম না থাকে যা আপনি ORDER BYকলাম হিসাবে পাস করতে পারেন (যেমন অন্যরা পরামর্শ দিয়েছেন), তবে আপনি এই কৌশলটি ব্যবহার করতে পারেন:

SELECT * FROM MyTable 
ORDER BY @@VERSION 
OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY

... বা

SELECT * FROM MyTable 
ORDER BY (SELECT 0)
OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY

ব্যবহারকারীরা স্পষ্টভাবে কোনও অর্ডার নির্দিষ্ট করে না এমন সময় আমরা এটি JOOQ এ ব্যবহার করছি । এটি কোনও অতিরিক্ত ব্যয় ছাড়াই বেশ এলোমেলো ক্রম উত্পাদন করবে।


6

আরও এবং বড় ডেটা কলাম সহ টেবিলগুলির জন্য, আমি পছন্দ করি:

SELECT 
  tablename.col1,
  tablename.col2,
  tablename.col3,
  ...
FROM
(
  (
    SELECT
      col1
    FROM 
    (
      SELECT col1, ROW_NUMBER() OVER (ORDER BY col1 ASC) AS RowNum
      FROM tablename
      WHERE ([CONDITION])
    )
    AS T1 WHERE T1.RowNum BETWEEN [OFFSET] AND [OFFSET + LIMIT]
  )
  AS T2 INNER JOIN tablename ON T2.col1=tablename.col1
);

-

[CONDITION] can contain any WHERE clause for searching.
[OFFSET] specifies the start,
[LIMIT] the maximum results.

এটি BLOB এর মতো বৃহত ডেটা সহ টেবিলগুলিতে আরও ভাল পারফরম্যান্স পেয়েছে, কারণ ROW_NUMBER ফাংশনটি কেবল একটি কলামের মধ্যে দেখতে হয় এবং কেবল সমস্ত মিলিয়ে সারিগুলি সমস্ত কলামের সাথে ফিরে আসে।


5

প্যাগিনেটর জন্য আমার নির্বাচন দেখুন

SELECT TOP @limit * FROM (
   SELECT ROW_NUMBER() OVER (ORDER BY colunx ASC) offset, * FROM (

     -- YOU SELECT HERE
     SELECT * FROM mytable


   ) myquery
) paginator
WHERE offset > @offset

এটি পৃষ্ঠাটি সমাধান করে;)


3
SELECT TOP 75 * FROM MyTable
EXCEPT 
SELECT TOP 50 * FROM MyTable

পারফরম্যান্স ওয়াইস যথোপযুক্ত বলে মনে হচ্ছে না কারণ অনাবশ্যকভাবে অযথা দুবার কার্যকর করা হয়েছে। বিশেষত ব্যবহারকারীর উচ্চতর পৃষ্ঠাগুলিতে যাওয়ার সাথে সাথে, সারিগুলি বাতিল করার ক্যোয়ারী যেমন EXCEPT এর নীচের অংশটি দীর্ঘ এবং দীর্ঘ সময় নেবে।
ভ্যানভাল

2

আপনার সংস্করণ অনুসারে ওউ এটি সরাসরি না করতে পারে তবে আপনি হ্যাকির মতো কিছু করতে পারেন

select top 25 *
from ( 
  select top 75 *
  from   table 
  order by field asc
) a 
order by field desc 

যেখানে 'ক্ষেত্র' চাবিকাঠি।


4
এসকিউএল 2000 এর জন্য যে সমাধানটি ফলাফলের সেটে শেষ পৃষ্ঠার জন্য কাজ করে না, যদি না পাতার মোট সংখ্যাটি পৃষ্ঠার আকারের একাধিক হয়ে থাকে।
বিল কারভিন 18

2

নিম্নলিখিতটি এসকিউএল সার্ভার ২০১২-এ প্রথম 50 টি রেকর্ড বাদ দিয়ে 25 টি রেকর্ড প্রদর্শন করবে।

SELECT * FROM MyTable ORDER BY ID OFFSET 50 ROWS FETCH NEXT 25 ROWS ONLY;

আপনি আপনার প্রয়োজন হিসাবে আইডি প্রতিস্থাপন করতে পারেন


প্লিজ, যোগ করুন এসকিউএল সার্ভার 2012 এ এটি সম্ভব
ইউসমান ইউনাস

2

ROW_NUMBER() OVER (ORDER BY)পারফরম্যান্সটি যথেষ্ট দুর্বল হওয়ায় বিবৃতিটি ব্যবহার করার সময় আপনার সতর্ক হওয়া উচিত । একই সাথে কমন সারণী এক্সপ্রেশনগুলি ব্যবহার ROW_NUMBER()করা আরও খারাপ। আমি নিম্নলিখিত স্নিপেটটি ব্যবহার করছি যা পৃষ্ঠার নম্বর সরবরাহের জন্য কোনও পরিচয় সহ একটি টেবিল ভেরিয়েবল ব্যবহার করার চেয়ে কিছুটা দ্রুত গতিযুক্ত প্রমাণিত হয়েছে।

DECLARE @Offset INT = 120000
DECLARE @Limit INT = 10

DECLARE @ROWCOUNT INT = @Offset+@Limit
SET ROWCOUNT @ROWCOUNT

SELECT * FROM MyTable INTO #ResultSet
WHERE MyTable.Type = 1

SELECT * FROM
(
    SELECT *, ROW_NUMBER() OVER(ORDER BY SortConst ASC) As RowNumber FROM
    (
        SELECT *, 1 As SortConst FROM #ResultSet
    ) AS ResultSet
) AS Page
WHERE RowNumber BETWEEN @Offset AND @ROWCOUNT

DROP TABLE #ResultSet

এই 11 সারি, না 10. ফিরে আসবে
হারুন বারট্রান্ড

1

আমি এই কৌশলটি পৃষ্ঠাগুলির জন্য ব্যবহার করি। আমি সব সারি আনা না। উদাহরণস্বরূপ, যদি আমার পৃষ্ঠাতে শীর্ষ 100 টি সারি প্রদর্শন করা দরকার তবে আমি যেখানে ক্লজ সহ 100 টি সারি নিয়েছি। এসকিউএল আউটপুট একটি অনন্য কী থাকা উচিত।

টেবিলে নিম্নলিখিত রয়েছে:

ID, KeyId, Rank

একই র‌্যাঙ্ক একাধিক কীআইডির জন্য বরাদ্দ করা হবে।

এসকিউএল হ'ল select top 2 * from Table1 where Rank >= @Rank and ID > @Id

উভয়ের জন্য প্রথমবারের মতো আমি পাস করেছি। দ্বিতীয়বার পাস 1 এবং 14. তৃতীয় বার পাস 2 এবং 6 ....

দশম রেকর্ড র‌্যাঙ্ক ও আইডির মান পরেরটিতে পাস করা হয়েছে

11  21  1
14  22  1
7   11  1
6   19  2
12  31  2
13  18  2

এটির সিস্টেমে সর্বনিম্ন চাপ থাকবে


1

SqlServer2005 এ আপনি নিম্নলিখিতগুলি করতে পারেন:

DECLARE @Limit INT
DECLARE @Offset INT
SET @Offset = 120000
SET @Limit = 10

SELECT 
    * 
FROM
(
   SELECT 
       row_number() 
   OVER 
      (ORDER BY column) AS rownum, column2, column3, .... columnX
   FROM   
     table
) AS A
WHERE 
 A.rownum BETWEEN (@Offset) AND (@Offset + @Limit-1) 

এটা করা উচিত নয় @Offset + @Limit - 1? @ লিমিট যদি 10 হয় তবে এটি 11 টি সারি ফিরিয়ে দেবে।
অ্যারন বারট্রান্ড

1

রেকর্ডগুলি অর্ডার করার জন্য সময় নষ্ট না করে এটি করার সর্বোত্তম উপায়:

select 0 as tmp,Column1 from Table1 Order by tmp OFFSET 5000000 ROWS FETCH NEXT 50 ROWS ONLY

এক সেকেন্ডেরও কম সময় লাগে!
বড় টেবিল জন্য সেরা সমাধান।


0

আমি এই উত্তরটি এখনই কিছু সময়ের জন্য অনুসন্ধান করেছি (জেনেরিক প্রশ্নের জন্য) এবং এসকিউএল সার্ভারে এটি করার আরও একটি উপায় 2000+ এবং ROWCOUNT এবং কার্সার ব্যবহার করে এবং শীর্ষস্থানীয় বা কোনও অস্থায়ী টেবিল ছাড়াই খুঁজে পেয়েছি।

ব্যবহার SET ROWCOUNT [OFFSET+LIMIT]আপনি ফলাফল সীমিত করতে পারেন, এবং এক্সিকিউটেবল-এর পাথ সঙ্গে, সারি ইচ্ছা, তারপর শেষ পর্যন্ত লুপ 'থেকে সরাসরি যান।

সুতরাং আপনার জিজ্ঞাসা এই মত হবে:

SET ROWCOUNT 75 -- (50 + 25)
DECLARE MyCursor SCROLL CURSOR FOR SELECT * FROM pessoas
OPEN MyCursor
FETCH ABSOLUTE 50 FROM MyCursor -- OFFSET
WHILE @@FETCH_STATUS = 0 BEGIN
    FETCH next FROM MyCursor
END
CLOSE MyCursor
DEALLOCATE MyCursor
SET ROWCOUNT 0

আপনি যখন টেবিলের শেষের দিকে পৌঁছে যাবেন তখন আমি এই অভিনয়টি দেখতে ঘৃণা করব ...
অ্যারন বারট্রান্ড

0

এসকিউএল সার্ভার ২০১২ (১১.x) এবং পরবর্তী এবং অ্যাজুরি এসকিউএল ডেটাবেস সহ আপনার "ফেচ_রো_কাউন্ট_এক্সপ্রেসন" থাকতে পারে, আপনার পাশাপাশি এই বিভাগের অর্ডারও থাকতে পারে।

USE AdventureWorks2012;  
GO  
-- Specifying variables for OFFSET and FETCH values    
DECLARE @skip int = 0  , @take int = 8;  
SELECT DepartmentID, Name, GroupName  
FROM HumanResources.Department  
ORDER BY DepartmentID ASC   
    OFFSET @skip ROWS   
    FETCH NEXT @take ROWS ONLY; 

https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql?view=sql-server-ver15

নোট অফফেস কোয়েরি এক্সপ্রেশন থেকে সারিগুলি ফেরত আসতে শুরু করার আগে এড়িয়ে যাওয়ার জন্য সারিগুলির সংখ্যা নির্দিষ্ট করে । এটি আরম্ভের সারির নম্বর নয়। সুতরাং, প্রথম রেকর্ডটি অন্তর্ভুক্ত করতে এটি 0 হতে হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.