এসকিউএল সার্ভারে সীমাবদ্ধ 10..20


161

আমি এরকম কিছু করার চেষ্টা করছি:

SELECT * FROM table LIMIT 10,20

অথবা

SELECT * FROM table LIMIT 10 OFFSET 10

তবে এসকিউএল সার্ভার ব্যবহার করছি

আমি খুঁজে পাওয়া একমাত্র সমাধানটি ওভারকিলের মতো দেখাচ্ছে:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE row > 5 and row <= 10

আমি এটিও পেয়েছি :

SELECT TOP 10 * FROM stuff; 

... তবে আমি এটি করতে চাই না কারণ আমি প্রারম্ভিক সীমাটি নির্দিষ্ট করতে পারি না।

আমার পক্ষে এটি করার জন্য অন্য কোনও উপায় আছে?

এছাড়াও, কেবল কৌতূহলী, এসকিউএল সার্ভার LIMITফাংশন বা অনুরূপ কিছু সমর্থন করে না এমন কোনও কারণ আছে কি? আমি বোঝাতে চাই না, তবে এটি সত্যিই ডিবিএমএসের মতো কিছু মনে হচ্ছে ... যদি তা হয় তবে আমি এত অজ্ঞ হওয়ার জন্য দুঃখিত! আমি গত 5 বছর ধরে মাইএসকিউএল এবং এসকিউএল + এর সাথে কাজ করছি তাই ...


1
সীমাটির প্রস্থের জন্য সিটিই ব্যবহার করা ROW_NUMBER()এবং TOPসীমার প্রস্থের জন্য সীমাবদ্ধ করা WHEREআমি অর্জন করতে সক্ষম হয়েছি এটি সেরা। আমি আরও ভাল পারফরম্যান্সের বিষয়টি লক্ষ্য করেছি যদি TOP
ক্লজটি

ROW_NUMBER () এর সাথে জড়িত যে কোনও সমাধানের সমস্যাটি হ'ল যদি আপনি কী কী কলামগুলি আগে থেকে আগেই না জানেন এবং আপনার যোগদান হয় এবং যোগদান করা টেবিলগুলির একই কলামের নাম থাকে তবে আপনি একটি "কলামটি পাবেন" 'xxx' একাধিকবার নির্দিষ্ট করা হয়েছিল "। এটি প্রথমদিকে যেমন শোনাচ্ছে তেমন অস্বাভাবিক নয়। আমি ড্যাপার ব্যবহার করি, এবং আমার টেবিলগুলিতে একটি আইডি কলাম রয়েছে। এতে ডিপার বিভক্ত হয়ে যায় এবং মানচিত্রগুলি, সুতরাং আমি তাদের নাম পরিবর্তন করতে চাই না, তবে আমি নির্বাচন করুন * ফরোম ([মূল জিজ্ঞাসা]) নাম ব্যবহার করতে পারি না। আমি এখনও একটি সমাধান বের করতে পারেনি!
স্টিভ ওভেন

উত্তর:


104

LIMITদফা মান এসকিউএল অংশ নয়। এটি এসকিউএল, মাইএসকিউএল, পোস্টগ্রেএসকিউএল এবং এসকিউএলাইট দ্বারা বিক্রেতার এক্সটেনশন হিসাবে সমর্থিত।

অন্যান্য ব্র্যান্ডের ডাটাবেসের একই বৈশিষ্ট্য থাকতে পারে (যেমন TOPমাইক্রোসফ্ট এসকিউএল সার্ভারে) তবে এগুলি সর্বদা অভিন্নভাবে কাজ করে না।

অনুচ্ছেদটি TOPঅনুকরণ করতে মাইক্রোসফ্ট এসকিউএল সার্ভারে এটি ব্যবহার করা শক্ত LIMIT। এমন কিছু ঘটনা রয়েছে যেখানে এটি ঠিক কাজ করে না।

আপনি যে সমাধানটি দেখিয়েছেন ROW_NUMBER()তা মাইক্রোসফ্ট এসকিউএল সার্ভার 2005 এবং তার পরে পাওয়া যায়। এটি সেরা সমাধান (বর্তমানে জন্য) যা সম্পূর্ণরূপে ক্যোয়ারির অংশ হিসাবে কাজ করে।

আর একটি সমাধান হ'ল TOPপ্রথম গণনা + অফসেট সারিগুলি আনার জন্য ব্যবহার করা এবং তারপরে প্রথম অফসেট সারিগুলি সন্ধান করার জন্য API ব্যবহার করুন ।

আরো দেখুন:


135

এসকিউএল সার্ভার ২০১২-এর জন্য আপনি ব্যবহার করতে পারেন

SELECT  *
FROM     sys.databases
ORDER BY name 
OFFSET  5 ROWS 
FETCH NEXT 5 ROWS ONLY 

10
আপনি যখন সীমাবদ্ধতা 5,5 ব্যবহার করেন তখন মাইএসকিউএল এবং এসকিউএলাইটের কেবল অর্ডার প্রয়োজন হয় না যখন আপনি সীমা 5,5 ব্যবহার করেন
টমাস কুবস 7:46 এ 14

4
@ qub1n - মাইএসকিউএল আপনাকে সেক্ষেত্রে কী সারি ফিরে পাবে তার গ্যারান্টি দেয় না
মার্টিন স্মিথ

3
আপনার কি ব্যবহার করতে হবে offset, বা আপনি কি এই লাইনটি ছেড়ে দিতে পারেন (ধরে নিচ্ছেন আপনি কোনও অফসেট চান না)?
কুল্লব


উদাহরণস্বরূপ আপনার জিজ্ঞাসাটি ঠিকঠাক চলছে তবে আমি যদি নীচের মতো করে টেবিলের নাম এবং ক্রমটি পরিবর্তন করি তবে প্রযোজ্য 5 টি সারি ফ্যাচটি পরবর্তী সারি থেকে 5 টি সারি অফ করুন * কেবল ত্রুটি দেয়Parse error at line: 4, column: 1: Incorrect syntax near 'OFFSET'
শাশওয়াত

36

যেমনটি আপনি পেয়েছেন, এটি পছন্দসই স্কেল সার্ভার পদ্ধতি:

SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name) as row FROM sys.databases 
 ) a WHERE a.row > 5 and a.row <= 10

কেন aঅন্তর্গতের পরে নির্বাচন? আমি ধরে নিচ্ছি আপনি অভ্যন্তরীণ নির্বাচনটি একটি উপনাম দিচ্ছেন, কিন্তু তারপরে আপনি কখনই এটি ব্যবহার করবেন বলে মনে হয় না ... তাহলে কি কেবল a.rowতার পরিবর্তে আপনি কি করা উচিত row?
লুকাস

3
@ লুকাস, আপনাকে উত্সযুক্ত ( )টেবিলের পরে একটি উপকরণ স্থাপন করা দরকার , তবে আপনি যদি কলামগুলি উল্লেখ করতে এটি ব্যবহার করতে ভুলে যান তবে এটি যেতে দেবে। যদিও আমি ঠিক করেছি ...
কেএম।

ধন্যবাদ, আমি খুঁজে পেলাম যে হার্ড পথটি (ওরফে খুঁজে বের করার চেষ্টা করা হয়েছে)।
লুকাস

1
ভোট দেওয়া +১: তবে, @ মার্টিনস্মিথের উত্তরটি আরও ভোট দেওয়া হয়েছে, এই পদ্ধতির সাথে এক্সিকিউশন প্ল্যানের তুলনা করার পরে, আমি জানতে পেরেছি যে, এই সমাধানটি দ্রুত কাজ করে।
হর্ষ

10

আপনি যদি এসকিউএল সার্ভার 2012+ ব্যবহার করছেন মার্টিন স্মিথের উত্তরের জন্য ভোট দিন এবং এতে OFFSETএবং FETCH NEXTএক্সটেনশানগুলি ব্যবহার করেন ORDER BY,

যদি আপনি পূর্ববর্তী সংস্করণে আটকে যাওয়ার জন্য দুর্ভাগ্যজনক হন তবে আপনি এরকম কিছু করতে পারেন,

WITH Rows AS
(
    SELECT
              ROW_NUMBER() OVER (ORDER BY [dbo].[SomeColumn]) [Row]
            , *
        FROM
              [dbo].[SomeTable]
)
SELECT TOP 10
          *
     FROM
         Rows
    WHERE Row > 10

আমি বিশ্বাস করি এর কার্যকারিতা সমান

SELECT * FROM SomeTable LIMIT 10 OFFSET 10 ORDER BY SomeColumn

এমএস এসকিউএল ২০১২ এর আগে, টিএসকিউএল-এ এটি করার সবচেয়ে ভাল পারফরম্যান্স way


যদি অনেকগুলি সারি থাকে তবে আপনি কোনও সিটিইর পরিবর্তে একটি টেম্প টেবিল ব্যবহার করে আরও ভাল পারফরম্যান্স পেতে পারেন।


২০১২-এর প্রাক সমাধান সমাধানের সময় মার্টিন স্মিথের জবাব (এবং এর সাথে লিঙ্ক করা) নির্দেশ করার জন্য উত্সাহিত। টেম্প টেবিল পরামর্শের
জন্যও

7

দুর্ভাগ্যক্রমে, ROW_NUMBER()আপনি সবচেয়ে ভাল করতে পারেন। এটি প্রকৃতপক্ষে আরও সঠিক, কারণ কোনও নির্দিষ্ট ক্রমের সম্মান না করে কোনও limitবা topদফা ফলাফলের সত্যিকার অর্থ হয় না। তবে এটি করার এখনও একটি ব্যথা।

আপডেট: এসকিএল সার্ভার ২০১২ অফসেট এবং ফেচ কীওয়ার্ডগুলিরlimit মাধ্যমে একটি পছন্দসই বৈশিষ্ট্য যুক্ত করেছে । এটি অ্যানসি-স্ট্যান্ডার্ড পদ্ধতির বিপরীতে , এটি একটি মানহীন মাই এসকিএল এক্সটেনশন।LIMIT


@ জোয়েল: আপনি কেন ব্যাখ্যা করতে পারবেন যে কেন ROW_NUMBER () সারণিগুলি অর্ডার দিয়ে যেভাবে বেরিয়ে আসে তার সংখ্যা নির্ধারণ করতে অক্ষম? আমি সর্বদা ভেবে দেখেছি কেন "ওভার (অর্ডার বাই নাম)" বাধ্যতামূলক, তবে আমি অনুমান করি যে এর পক্ষে যুক্তিসঙ্গত কারণ রয়েছে। বা কমপক্ষে একটি কারণ।
টমলক

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

1
@মারসিজিজি: মাইক্রোসফ্ট যে সীমাবদ্ধতা প্রয়োগের পরিকল্পনা করছে তার কোনও ইঙ্গিত আমি কখনই পড়িনি। এমনকি যদি তাদের কাছে এমন পরিকল্পনা থাকে তবে ক্লোজড-সোর্স বিক্রেতারা বৈশিষ্ট্যগুলি প্রাক-ঘোষণার দিকে ঝুঁকেন না। এটি অবশ্যই একটি সহায়ক বৈশিষ্ট্য হবে, তবে আমরা জানি না যে তাদের কোডের ভিত্তিতে এটি বাস্তবায়নের জন্য কতটা কাজ হবে।
বিল কারভিন

3
আপনি যদি অর্ডার বাই ক্লজে নিজেকে পুনরাবৃত্তি করতে না চান, তবে কলামগুলির মূল সেটের পরিবর্তে ROW_NUMBER () নাম ব্যবহার করুন।
পিটার রডোচিয়া

2
@ তোমালাক: যতক্ষণ এসকিউএল সার্ভারের সাথে সম্পর্কিত, ROW_NUMBER () গণনা করার জন্য ব্যবহৃত ক্রমটি ফলাফলের আদেশের সাথে পুরোপুরি সম্পর্কিত নয়। এজন্য আপনাকে সেগুলি আলাদাভাবে নির্দিষ্ট করতে হবে।
লুক এইচ

6

এ কেমন?

SET ROWCOUNT 10 

SELECT TOP 20 *
FROM sys.databases
ORDER BY database_id DESC

এটি আপনাকে প্রথম 20 টি সারির শেষ 10 টি সারি দেয়। একটি অপূর্ণতা হ'ল অর্ডারটি বিপরীত হয়েছে তবে কমপক্ষে এটি মনে রাখা সহজ।


6
টেবিলে কেবল 14 সারি থাকলে কী হবে? আপনি 14-এর নিচে সারি পান, যা সীমা 10 টি অফসেট 10 দ্বারা সরিয়ে ফেলা সমান নয় (14 থেকে নীচে সারি হওয়া উচিত)।
বিল কারভিন

2
SELECT TOP 10 *
FROM TABLE
WHERE IDCOLUMN NOT IN (SELECT TOP 10 IDCOLUMN FROM TABLE)

রেকর্ড 11-20 দেওয়া উচিত। আরও পৃষ্ঠাগুলি পেতে ইনক্রিমেন্টিং করা সম্ভবত খুব বেশি দক্ষ নয় এবং অর্ডার দিয়ে কীভাবে এটি প্রভাবিত হতে পারে তা নিশ্চিত নয়। উভয় WHERE বিবৃতিতে এটি নির্দিষ্ট করতে হবে।


1

একটি পদ্ধতি তৈরি করা একটি ভাল উপায়:

create proc pagination (@startfrom int ,@endto int) as
SELECT * FROM ( 
  SELECT *, ROW_NUMBER() OVER (ORDER BY name desc) as row FROM sys.databases 
 ) a WHERE a.row > @startfrom and a.row <= @endto

যেমন সীমা 0,2 /////////////// পৃষ্ঠা সম্পাদন 0,4 চালানো


1

সর্বাধিক দক্ষ না হলেও সবেমাত্র রেকর্ড সমাধানের জন্য যা বেশিরভাগ ডাটাবেস ইঞ্জিনগুলিতে কাজ করে:

Select Top (ReturnCount) *
From (
    Select Top (SkipCount + ReturnCount) *
    From SourceTable
    Order By ReverseSortCondition
) ReverseSorted
Order By SortCondition

পেলেস দ্রষ্টব্য: স্কিপকাউন্ট যাই হোক না কেন শেষ পৃষ্ঠায় রিটার্নকাউন্ট সারি থাকবে। তবে এটি অনেক ক্ষেত্রে ভাল জিনিস হতে পারে।


1

লিমিটেডের সমতুল্য সেট রুট অ্যাকাউন্ট, তবে আপনি যদি জেনেরিক পৃষ্ঠাগুলি চান তবে এই জাতীয় একটি কোয়েরি লিখাই ভাল:

;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

0
select * from (select id,name,ROW_NUMBER() OVER (ORDER BY id  asc) as row
from tableName1) tbl1
where tbl1.row>=10 and tbl1.row<=15

10 থেকে 15 পর্যন্ত সারিগুলি মুদ্রণ করবে।


0

এখনও অবধি এই ফর্ম্যাটটি আমার পক্ষে কাজ করছে (যদিও সেরা পারফরম্যান্স নয়):

SELECT TOP {desired amount of rows} * 
FROM (SELECT *, ROW_NUMBER() OVER (ORDER BY {order columns} asc)__row__ FROM {table})tmp
WHERE __row__ > {offset row count}

পার্শ্বে একটি নোট, ডায়নামিক ডেটা নিয়ে পৃষ্ঠপোষককরণ অদ্ভুত / অপ্রত্যাশিত ফলাফলের দিকে নিয়ে যেতে পারে।


0

এমএস এসকিউএল সার্ভার অনলাইন ডকুমেন্টেশন ( http://technet.microsoft.com/en-us/library/ms186734.aspx ) থেকে, সারিগুলির একটি নির্দিষ্ট সেট পুনরুদ্ধার করার জন্য আমি তাদের উদাহরণটি পরীক্ষা করেছি এবং কাজ করেছি। ROW_NUMBER এর জন্য একটি ওভার দরকার, তবে আপনি যা পছন্দ করেন তার মাধ্যমে আদেশ দিতে পারেন:

WITH OrderedOrders AS
(
  SELECT SalesOrderID, OrderDate,
  ROW_NUMBER() OVER (ORDER BY OrderDate) AS RowNumber
  FROM Sales.SalesOrderHeader 
) 
SELECT SalesOrderID, OrderDate, RowNumber  
FROM OrderedOrders 
WHERE RowNumber BETWEEN 50 AND 60;

0

সমস্ত এসকিউএল সার্ভার ব্যবহার করুন:; টিবিএল হিসাবে (নির্বাচন করুন ROW_NUMBER () ওভার (ক্রমান্বয়ে ইন্ডেক্স হিসাবে 1 টি নির্বাচন করুন), টেবিল থেকে * টিবিএল থেকে শীর্ষ 10 * নির্বাচন করুন যেখানে রোইইন্ডেক্স> = 10


-3
 SELECT * FROM users WHERE Id Between 15 and 25

এটি এমওয়াইএসকিউএলে সীমা হিসাবে 15 থেকে 25 পর্যন্ত মুদ্রণ করবে


2
যদি ব্যবহারকারী 15 এবং 25 এর মধ্যে একটি রেকর্ড মুছে ফেলেন?
Gökçer Gökdal
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.