एसक्यूएल सर्वर में लिमिट 10..20


161

मैं कुछ करने की कोशिश कर रहा हूँ:

SELECT * FROM table LIMIT 10,20

या

SELECT * FROM table LIMIT 10 OFFSET 10

लेकिन SQL सर्वर का उपयोग कर

एकमात्र समाधान जो मुझे मिला वह ओवरकिल जैसा दिखता है:

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; 

... लेकिन यह वह नहीं है जो मैं करना चाहता हूं क्योंकि मैं शुरुआती सीमा निर्दिष्ट नहीं कर सकता।

क्या मेरे लिए ऐसा करने का कोई और तरीका है?

इसके अलावा, बस उत्सुक, वहाँ एक कारण है कि SQL सर्वर LIMITफ़ंक्शन या कुछ इसी तरह का समर्थन नहीं करता है ? मैं मतलबी नहीं होना चाहता, लेकिन यह वास्तव में एक DBMS की जरूरत है कुछ की तरह लगता है ... अगर यह करता है, तो मुझे इतना अज्ञानी होने के लिए खेद है! मैं पिछले 5 वर्षों से MySQL और SQL + के साथ काम कर रहा हूँ ...


1
सीमा की चौड़ाई के लिए CTE का उपयोग करना ROW_NUMBER()और सीमित करना TOPऔर सीमा WHEREके एक सीमा के लिए एक शर्त सबसे अच्छा है जिसे मैं प्राप्त करने में सक्षम हूं। मैं भी बेहतर प्रदर्शन देखा है अगर TOPखंड के बजाय एक शाब्दिक का उपयोग करता है चर का
Jodrell

ROW_NUMBER () को शामिल करने वाले किसी भी समाधान के साथ समस्या यह है कि यदि आपको पहले से पता नहीं है कि आपके पास कौन से कॉलम हैं, और आप जुड़ गए हैं, और शामिल किए गए तालिकाओं में समान कॉलम नाम है, तो आपको "कॉलम" मिलेगा 'xxx' को कई बार निर्दिष्ट किया गया था। यह उतना असामान्य नहीं है जितना यह शुरू में लग सकता है। मैं Dapper का उपयोग करता हूं, और मेरे सभी तालिकाओं में एक Id कॉलम है। उस पर डैपर विभाजन और नक्शे, इसलिए मैं उनका नाम नहीं बदलना चाहता, लेकिन मैं सेलेक्ट * FROM ([मूल क्वेरी]) उपनाम का उपयोग नहीं कर सकता। मैं अभी तक एक समाधान नहीं है!
स्टीव ओवेन

जवाबों:


104

LIMITखंड मानक SQL का हिस्सा नहीं है। यह MySQL, PostgreSQL और SQLite द्वारा SQL के लिए एक विक्रेता विस्तार के रूप में समर्थित है।

डेटाबेस के अन्य ब्रांडों में समान विशेषताएं हो सकती हैं (जैसे TOPMicrosoft SQL सर्वर में), लेकिन ये हमेशा पहचान के काम नहीं करते हैं।

क्‍लॉज की TOPनकल करने के लिए Microsoft SQL Server में उपयोग करना कठिन है LIMIT। ऐसे मामले हैं जहां यह काम नहीं करता है।

आपने जो समाधान दिखाया, ROW_NUMBER()उसका उपयोग Microsoft SQL Server 2005 और बाद में उपलब्ध है। यह (अभी के लिए) सबसे अच्छा समाधान है जो पूरी तरह से क्वेरी के हिस्से के रूप में काम करता है।

एक और उपाय TOPपहली गिनती + ऑफसेट पंक्तियों को लाने के लिए उपयोग करना है , और फिर पहले ऑफसेट पंक्तियों की तलाश करने के लिए एपीआई का उपयोग करना है ।

यह सभी देखें:


135

SQL सर्वर 2012 + के लिए आप उपयोग कर सकते हैं

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

10
SQl Server 2012 को जब आप OFFSET 5 ROWS FETCH NEXT 5 ROWS का उपयोग करते हैं तब केवल आपको ORITER निर्दिष्ट करना पड़ता है जबकि MySql और SQLite को तब आदेश की आवश्यकता नहीं होती है जब आप LIMIT 5,5 का उपयोग करते हैं
Tomus Kubes

4
@ qub1n - MySQL इस बात की गारंटी नहीं देता है कि आपको उस मामले में क्या पंक्तियाँ मिलती हैं।
मार्टिन स्मिथ

3
क्या आपको उपयोग करना है offset, या क्या आप उस लाइन को छोड़ सकते हैं (यह मानते हुए कि आपको ऑफसेट नहीं चाहिए)?
कुल्लूब


आप उदाहरण क्वेरी ठीक चलता है, लेकिन अगर मैं चयन नीचे के रूप में col द्वारा तालिका नाम और क्रम बदलने * से DimProduct आदेश द्वारा ProductKey 5 पंक्तियाँ OFFSET FETCH अगले 5 पंक्तियाँ ही यह त्रुटि देता हैParse error at line: 4, column: 1: Incorrect syntax near 'OFFSET'
Shashwat

36

जैसा कि आपने पाया, यह पसंदीदा sql सर्वर विधि है:

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
वोट किया +1: हालांकि, @MartinSmith का जवाब अधिक मतदान है, इस दृष्टिकोण के साथ निष्पादन योजना की तुलना करने के बाद, मुझे पता चला कि, यह समाधान तेजी से काम करता है।
हर्ष

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

और सबसे अच्छा प्रदर्शन करने का तरीका जो मैं MS SQL 2012 से पहले TSQL में करने का जानता हूं।


यदि बहुत सी पंक्तियाँ हैं, तो आपको CTE के बजाय एक अस्थायी तालिका का उपयोग करके बेहतर प्रदर्शन मिल सकता है।


2012 के पूर्व समाधान प्रदान करते समय मार्टिन स्मिथ के उत्तर (और इसे लिंक करने के लिए) की ओर इशारा करते हुए। इसके अलावा अस्थायी तालिका सलाह के लिए क्योंकि आप सही हैं :)
फूजीफेस

7

दुर्भाग्य से, ROW_NUMBER()सबसे अच्छा आप कर सकते हैं। यह वास्तव में अधिक सही है, क्योंकि किसी विशिष्ट क्रम के संबंध में limitया किसी topखंड के परिणाम का वास्तव में अर्थ नहीं है। लेकिन यह अभी भी एक दर्द है।

अद्यतन: Sql सर्वर 2012 OFFSET और FETCH कीवर्ड केlimit माध्यम से एक समान सुविधा जोड़ता है । यह एएनएसआई-मानक दृष्टिकोण है , जिसका विरोध एक गैर-मानक MySql एक्सटेंशन है।LIMIT


@ जॉयल: क्या आप बता सकते हैं कि ROW_NUMBER () ORDER BY से बाहर आने वाली पंक्तियों की संख्या को बताने में असमर्थ है? मैंने हमेशा सोचा है कि "OVER (ORDER BY नाम)" क्यों अनिवार्य है, लेकिन मुझे लगता है कि इसके लिए एक अच्छा कारण है। या कम से कम एक कारण।
तोमलक

3
क्योंकि खंड द्वारा आदेश के बिना आदेश जैसी कोई चीज नहीं है। आपको रिकॉर्ड जो भी आदेश सर्वर को उपलब्ध थे, और जो क्वेरी अनुरोध से क्वेरी अनुरोध में बदल सकते हैं
जोएल कोएहॉर्न

1
@marcgg: मैंने कभी भी ऐसा कोई संकेत नहीं पढ़ा कि Microsoft की योजना LIMIT को लागू करने की है। यहां तक ​​कि अगर उनके पास ऐसी योजना है, तो बंद-स्रोत विक्रेता सुविधाओं की पूर्व-घोषणा नहीं करते हैं। यह निश्चित रूप से एक सहायक सुविधा होगी, लेकिन हमें पता नहीं है कि इसे लागू करने के लिए कितना काम होगा, उनके कोड को देखते हुए।
बिल कार्विन

3
यदि आप ORDER BY खंड में खुद को दोहराना नहीं चाहते हैं, तो स्तंभों के मूल सेट के बजाय ROW_NUMBER () उपनाम का उपयोग करें।
पीटर रैडोचिया

2
@Tomalak: जहाँ तक SQL सर्वर का संबंध है, ROW_NUMBER () की गणना करने के लिए उपयोग किया जाने वाला आदेश परिणामी के क्रम से पूरी तरह असंबंधित है। इसलिए आपको उन्हें अलग से निर्दिष्ट करना होगा।
ल्यूक

6

इस बारे में कैसा है?

SET ROWCOUNT 10 

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

यह आपको पहले 20 पंक्तियों की अंतिम 10 पंक्तियाँ देता है। एक कमी यह है कि आदेश उलटा है, लेकिन, कम से कम यह याद रखना आसान है।


6
यदि तालिका में केवल 14 पंक्तियाँ हैं तो क्या होगा? आपको पंक्तियों में 14 से 5 तक की पंक्तियाँ मिलती हैं, जो कि LIMIT 10 OFFSET 10 द्वारा दी गई पंक्तियों के समान नहीं है (पंक्तियों की संख्या 14 से नीचे 11 होनी चाहिए)।
बिल कार्विन

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

11-20 रिकॉर्ड देना चाहिए। संभवतः बहुत अधिक कुशल नहीं अगर आगे के पेज पाने के लिए वेतन वृद्धि हो, और यह सुनिश्चित न हो कि आदेश देने से यह कैसे प्रभावित हो सकता है। दोनों विवरणों में इसे निर्दिष्ट करना पड़ सकता है।


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

MS SQL Server ऑनलाइन दस्तावेज़ ( http://technet.microsoft.com/en-us/library/ms186734.aspx ) से, यहां उनका उदाहरण है कि मैंने परीक्षण किया है और पंक्तियों के एक विशिष्ट सेट को पुनः प्राप्त करने के लिए काम करता है। ROW_NUMBER को एक OVER की आवश्यकता होती है, लेकिन आप जो चाहें उसे ऑर्डर कर सकते हैं:

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

सभी SQL सर्वर का उपयोग करें: के साथ tbl के रूप में (SELECT ROW_NUMBER () ओवर (ऑर्डर 1 द्वारा (ऑर्डर करें)) को RowIndex के रूप में, * तालिका से) शीर्ष 10 * tbl से चुनें जहां RowIndex> = 10


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

यह MYSQl में सीमा के अनुसार 15 से 25 तक प्रिंट करेगा


2
यदि उपयोगकर्ता ने 15 और 25 के बीच कोई रिकॉर्ड हटा दिया है तो क्या होगा?
गोकेर गोकलड
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.