SQL सर्वर में परिणामों को पृष्ठांकित करने का सबसे अच्छा तरीका क्या है


474

SQL Server 2000, 2005, 2008, 2012 में परिणामों को पृष्ठांकित करने का सबसे अच्छा तरीका (प्रदर्शन वार) है यदि आप भी कुल परिणाम प्राप्त करना चाहते हैं (पेजिंग से पहले)?


26
मुझे हमेशा आश्चर्य होता है कि उन्होंने सिर्फ TOP के भाग के रूप में एक ऑफसेट को निर्दिष्ट करने का समर्थन क्यों नहीं किया (जैसे MySQL / Posgresql समर्थन के साथ LIMIT / OFFSET)। उदाहरण के लिए, उनके पास सिंटैक्स "SELECT TOP x, y ...." हो सकता है, जहां x = पंक्तियों की संख्या, y = ऑफसेट ऑफसेट। यह भी पीछे संगत होगा।
ग्रिग्मैक सिप

3
हे, मुझे भी ... एसक्यूएल के 2005 पृष्ठांकन कार्यान्वयन यह वास्तव में बहुत akward है ...
खुलता है

6
@gregmac - Sql Server 2012 में अभी सीमा / ऑफसेट नहीं है।
ऊँ

2
स्वीकृत समाधान यह नहीं दिखाता है कि यह सबसे अच्छा तरीका (प्रदर्शन वार) कैसे है। कोई भी डेटा बड़े डेटा सेट पर इसका समर्थन करता है?
OOO

3
@OO: यहां एक अच्छा बेंचमार्क पाया जा सकता है: 4guysfromrolla.com/webtech/042606-1.shtml । हालाँकि, खोज विधि किसी भी ऑफसेट-आधारित पृष्ठांकन को बेहतर बनाएगी।
लुकास एडर

जवाबों:


465

परिणामों की कुल संख्या प्राप्त करना और पेजिंग दो अलग-अलग ऑपरेशन हैं। इस उदाहरण के लिए, मान लें कि आप जिस क्वेरी से निपट रहे हैं

SELECT * FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate

इस स्थिति में, आप उपयोग करके परिणामों की कुल संख्या निर्धारित करेंगे:

SELECT COUNT(*) FROM Orders WHERE OrderDate >= '1980-01-01'

... जो अक्षम लग सकता है, लेकिन वास्तव में बहुत अच्छा प्रदर्शन करने वाला, सभी सूचकांक आदि को ठीक से स्थापित करने वाला है।

अगला, पृष्ठांकित फैशन में वास्तविक परिणाम वापस पाने के लिए, निम्नलिखित प्रश्न सबसे अधिक कुशल होगा:

SELECT  *
FROM    ( SELECT    ROW_NUMBER() OVER ( ORDER BY OrderDate ) AS RowNum, *
          FROM      Orders
          WHERE     OrderDate >= '1980-01-01'
        ) AS RowConstrainedResult
WHERE   RowNum >= 1
    AND RowNum < 20
ORDER BY RowNum

यह मूल क्वेरी की पंक्तियाँ 1-19 लौटाएगा। यहाँ विशेष रूप से वेब ऐप्स के लिए अच्छी बात यह है कि आपको किसी भी राज्य को रखने की आवश्यकता नहीं है, केवल पंक्ति संख्याओं को छोड़कर।


37
बस ध्यान दें कि SQL Server 2000 में ROW_NUMBER () मौजूद नहीं है
जॉन हंटर

6
क्या यह आंतरिक क्वेरी से सभी पंक्तियों को वापस करता है और फिर बाहरी क्वेरी के आधार पर फ़िल्टर करता है? पूर्व के लिए: आंतरिक क्वेरी 100,000 और बाहरी क्वेरी केवल 20.
SoftwareGeek

2
@SoftwareGeek: इसे उपकेंद्र (आंतरिक क्वेरी) के रूप में सोचें जो एक धारा को लौटाता है, जो तब तक पढ़ा जाता है जब तक कि बाहरी WHERE क्लॉज संतुष्ट नहीं हो जाता। पंक्तियों को कैसे शामिल किया जा सकता है, यह पूरी तरह से क्वेरी पर निर्भर करता है, लेकिन ऑप्टिमाइज़र आमतौर पर उस संख्या को कम करने पर बहुत अच्छा काम करता है। SQL सर्वर प्रबंधन स्टूडियो में ग्राफ़िकल एक्ज़ीक्यूशन प्लान व्यूअर का उपयोग करना (क्वैरी / एक्चुअल एक्ज़ीक्यूटिव प्लान शामिल करें) उस संबंध में बहुत शैक्षिक है।
एमडीबी

2
ठीक है, क्या होगा अगर आप आंतरिक चयन में (जैसे कि जब आप आंतरिक रूप से जुड़ते हैं) आप कैसे अलग-अलग उपयोग करते हैं क्योंकि
रोवनम्बर

10
Microsoft ने SQL 2012 में एक नई सुविधा जोड़ी है जो MySQL के समान पृष्ठांकन बनाता है। यह जानने के लिए इस लिंक का अनुसरण करें। यह एक दिलचस्प लेख है: dbadiaries.com/…
Arash

511

अंत में, Microsoft SQL Server 2012 जारी किया गया था, मुझे वास्तव में एक पृष्ठांकन के लिए इसकी सादगी पसंद है, आपको यहां दिए गए प्रश्नों जैसे जटिल प्रश्नों का उपयोग करने की आवश्यकता नहीं है।

अगली 10 पंक्तियाँ प्राप्त करने के लिए बस इस क्वेरी को चलाएं:

SELECT * FROM TableName ORDER BY id OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY;

https://docs.microsoft.com/en-us/sql/t-sql/queries/select-order-by-clause-transact-sql#using-offset-and-fetch-to-limit-the-rows- लौटा हुआ

इसका उपयोग करते समय विचार करने के लिए मुख्य बिंदु:

  • ORDER BYOFFSET ... FETCHक्लॉज का उपयोग करना अनिवार्य है
  • OFFSETके साथ क्लॉज अनिवार्य है FETCH। आप उपयोग नहीं कर सकते ORDER BY ... FETCH
  • TOPके साथ OFFSETऔर FETCHएक ही क्वेरी अभिव्यक्ति में संयुक्त नहीं किया जा सकता है ।

12
अभी भी इंतजार कर रहा है LISTAGG()/ GROUP_CONCAT()
बेकन

1
@BaconBits इस जवाब के साथ इसे करने का एक डरपोक तरीका देखें FOR XML: stackoverflow.com/a/273330/429949
रिचर्ड मार्सेल - Drackir

1
@ RichardMarskell-Drackir के साथ बहुत सारी समस्याएं हैं FOR XML PATH ('')। सबसे पहले, यह XML नियंत्रण वर्णों को XML निकाय कोड के साथ बदल देता है। आशा है कि आप की जरूरत नहीं है <, >या &आपके डेटा में! दूसरा, FOR XML PATH ('')इस तरीके से उपयोग किया जाना वास्तव में अनिर्दिष्ट वाक्य रचना है। आपको एक नामित कॉलम या एक वैकल्पिक तत्व नाम निर्दिष्ट करना चाहिए। न तो करना डॉक्टर में नहीं है, जिसका अर्थ है कि व्यवहार अविश्वसनीय है। तीसरा, जितना अधिक हम टूटे हुए FOR XML PATH ('')वाक्यविन्यास को स्वीकार करते हैं , उतना ही कम संभावना है कि एमएस वास्तव में एक वास्तविक LISTAGG() [ OVER() ] फ़ंक्शन प्रदान करता है जैसे उन्हें आवश्यक है।
बेकन बिट्स

4
शर्म बहुत बुरा है mssqlgirl.com/ ...
जॉन

5
@Jon, कि लिंक की गई ब्लॉग पोस्ट प्रतिनिधि नहीं है, इस अर्थ में यह आईडी कॉलम के मूल्यों को देखते हुए पृष्ठ परिणाम वापस करने के आधार पर तुलना करता है।
नोएल अब्राहम

103

अविश्वसनीय रूप से, किसी भी अन्य उत्तर ने सभी SQL सर्वर संस्करणों में पृष्ठांकन करने का सबसे तेज़ तरीका नहीं बताया है । बड़े पृष्ठ संख्याओं के लिए ऑफ़सेट बहुत धीमे हो सकते हैं, जैसा कि यहां बेंचमार्क किया गया है । SQL में पेजेशन करने के लिए एक पूरी तरह से अलग, बहुत तेज़ तरीका है। जैसा कि यहाँ इस ब्लॉग पोस्ट में वर्णित है, इसे अक्सर "सीक विधि" या "कीसेट पेजेशन" कहा जाता है

SELECT TOP 10 first_name, last_name, score, COUNT(*) OVER()
FROM players
WHERE (score < @previousScore)
   OR (score = @previousScore AND player_id < @previousPlayerId)
ORDER BY score DESC, player_id DESC

"तलाश करें"

@previousScoreऔर @previousPlayerIdमूल्यों पिछले पृष्ठ से पिछले रिकॉर्ड के संबंधित मूल्यों कर रहे हैं। यह आपको "अगला" पृष्ठ लाने की अनुमति देता है। यदि ORDER BYदिशा है ASC, तो >इसके बजाय बस का उपयोग करें ।

उपरोक्त विधि के साथ, आप पहले पिछले 40 रिकॉर्ड प्राप्त किए बिना तुरंत पृष्ठ 4 पर नहीं जा सकते। लेकिन अक्सर, आप वैसे भी कूदना नहीं चाहते हैं। इसके बजाय, आपको एक बहुत तेज़ क्वेरी मिलती है जो आपके अनुक्रमण के आधार पर निरंतर समय में डेटा लाने में सक्षम हो सकती है। साथ ही, आपके पृष्ठ "स्थिर" बने रहते हैं, इससे कोई फर्क नहीं पड़ता कि अंतर्निहित डेटा बदलता है (उदाहरण पृष्ठ 1 पर, जबकि आप पृष्ठ 4 पर हैं)।

उदाहरण के लिए, वेब अनुप्रयोगों में अधिक डेटा लोड करने पर आलसी होने के लिए यह सबसे अच्छा तरीका है।

ध्यान दें, "तलाश विधि" को कीसेट पेजिंग भी कहा जाता है ।

अंकुरण से पहले कुल रिकॉर्ड

COUNT(*) OVER()खिड़की समारोह आप "पृष्ठांकन से पहले" कुल अभिलेखों की संख्या गिनती में मदद मिलेगी। यदि आप SQL Server 2000 का उपयोग कर रहे हैं, तो आपको SQL के लिए दो प्रश्नों का सहारा लेना होगा COUNT(*)


2
@ user960567: प्रदर्शन के संदर्भ में, कीसेट पेजिंग हमेशा ऑफ़सेट पेजिंग को हरा देगी, चाहे आप SQL मानक के साथ ऑफ़सेट पेजिंग को लागू करें OFFSET .. FETCHया पिछले ROW_NUMBER()ट्रिक्स के साथ ।
लुकास ईडर

21
मैं तीन तरीकों की तलाश कर रहा हूं। [१] एक उपयोगकर्ता पेज पर नहीं जा सकता। [२] यह अनुक्रमिक कुंजियों को मानता है अर्थात यदि कोई ३ पंक्तियों को हटाता है, तो मुझे १० के बजाय instead वस्तुओं का एक पृष्ठ मिलता है। RowNumberमुझे प्रति पृष्ठ १० आइटम लगातार मिलते हैं । [३] यह मौजूदा ग्रिडों के साथ काम नहीं करता है जो ग्रहण करते हैं pagenumberऔर pagesize
रेबेका

7
@ जूनो: कीसेट पेजिंग सभी मामलों के लिए उपयुक्त नहीं है। यह निश्चित रूप से डेटा ग्रिड के लिए नहीं है। लेकिन यह फेसबुक फीड पेज की अनंत स्क्रॉलिंग जैसे परिदृश्यों के लिए एकदम सही है। इससे कोई फर्क नहीं पड़ता कि शीर्ष पर नए पोस्ट जोड़े जा रहे हैं, आपके बाद के फीड पोस्ट सही तरीके से नीचे जोड़ दिए जाएंगे, जबकि आप नीचे स्क्रॉल कर रहे हैं। इसके लिए सही उपयोग उदाहरण ... ऐसी चीज़ों को केवल संख्याओं का उपयोग करके ऑफ़सेट सीमा / प्राप्त करने का उपयोग करने के लिए बहुत अधिक कठिन होगा ।
रॉबर्ट कोरिटनिक

4
मुझे जूनो से सहमत होना होगा। यह विधि पूरी तरह से एक ग्राहक को नियंत्रित करती है जिसमें "पिछला 1 2 3 (4) 5 6 अगला" का एक सुंदर मानक पृष्ठांकन है, जहां उपयोगकर्ता आगे कूद सकते हैं। मेरे अनुभव में यह बिल्कुल किनारे का मामला नहीं है ...
एरोनएचएस

3
कुंजी समुच्चय पृष्ठांकन लेख यहाँ
Stphane

31

एसक्यूएल सर्वर 2012 से, हम उपयोग कर सकते हैं OFFSETऔर FETCH NEXTखण्ड पृष्ठांकन प्राप्त करने के लिए।

SQL सर्वर के लिए यह प्रयास करें:

SQL सर्वर 2012 में एक नए डेटा को एक सेट डेटा के अनुकूलन के लिए ORDER BY क्लॉज में जोड़ा गया था, जो कि T-SQL में लिखने वाले और SQL सर्वर में संपूर्ण निष्पादन योजना के लिए डेटा पेजिंग के साथ काम को आसान बनाता है।

पिछले उदाहरण में उपयोग किए गए एक ही तर्क के साथ टी-एसक्यूएल स्क्रिप्ट के नीचे।

--CREATING A PAGING WITH OFFSET and FETCH clauses IN "SQL SERVER 2012"
DECLARE @PageNumber AS INT, @RowspPage AS INT
SET @PageNumber = 2
SET @RowspPage = 10 
SELECT ID_EXAMPLE, NM_EXAMPLE, DT_CREATE
FROM TB_EXAMPLE
ORDER BY ID_EXAMPLE
OFFSET ((@PageNumber - 1) * @RowspPage) ROWS
FETCH NEXT @RowspPage ROWS ONLY;

TechNet: SQL सर्वर के साथ एक क्वेरी पेजिंग


इस परीक्षण में सबसे सटीक जवाब
विक्रांत

17

MSDN: ROW_NUMBER (Transact-SQL)

एक परिणाम सेट के एक विभाजन के भीतर एक पंक्ति की अनुक्रमिक संख्या देता है, प्रत्येक विभाजन में पहली पंक्ति के लिए 1 से शुरू होता है।

निम्न उदाहरण ऑर्डरडेट के क्रम में 50 से 60 की संख्या के साथ पंक्तियाँ देता है।

WITH OrderedOrders AS
(
    SELECT
        ROW_NUMBER() OVER(ORDER BY FirstName DESC) AS RowNumber, 
        FirstName, LastName, ROUND(SalesYTD,2,1) AS "Sales YTD"
    FROM [dbo].[vSalesPerson]
) 
SELECT RowNumber, 
    FirstName, LastName, Sales YTD 
FROM OrderedOrders 
WHERE RowNumber > 50 AND RowNumber < 60;
  RowNumber FirstName    LastName               SalesYTD
  --- -----------  ---------------------- -----------------
  1   Linda        Mitchell               4251368.54
  2   Jae          Pak                    4116871.22
  3   Michael      Blythe                 3763178.17
  4   Jillian      Carson                 3189418.36
  5   Ranjit       Varkey Chudukatil      3121616.32
  6   José         Saraiva                2604540.71
  7   Shu          Ito                    2458535.61
  8   Tsvi         Reiter                 2315185.61
  9   Rachel       Valdez                 1827066.71
  10  Tete         Mensa-Annan            1576562.19
  11  David        Campbell               1573012.93
  12  Garrett      Vargas                 1453719.46
  13  Lynn         Tsoflias               1421810.92
  14  Pamela       Ansman-Wolfe           1352577.13

15

Http://www.codeproject.com/KB/aspnet/PagingLarge.aspx पर विभिन्न पेजिंग तकनीकों का अच्छा अवलोकन है

मैंने बहुत बार SQL Server 2000 के साथ ROWCOUNT पद्धति का उपयोग किया है (यह 2005 और 2008 के साथ भी काम करेगा, बस ROW_NUMBER की तुलना में प्रदर्शन को मापें), यह तेज़ बिजली है, लेकिन आपको यह सुनिश्चित करने की आवश्यकता है कि सॉर्ट किए गए कॉलम (अधिकतर) हैं ) अद्वितीय मूल्य।


1
दिलचस्प बात यह है कि उस लेख में उस शोध पद्धति का उल्लेख नहीं है , जो निरंतर समय में पेजिंग करने में सक्षम है ... फिर भी एक अच्छा लेख
लुकास ईडर

6

SQL Server 2000 के लिए आप ROW_NUMBER () को एक ID चर के साथ एक पहचान कॉलम के साथ अनुकरण कर सकते हैं:

DECLARE @pageNo int -- 1 based
DECLARE @pageSize int
SET @pageNo = 51
SET @pageSize = 20

DECLARE @firstRecord int
DECLARE @lastRecord int
SET @firstRecord = (@pageNo - 1) * @pageSize + 1 -- 1001
SET @lastRecord = @firstRecord + @pageSize - 1   -- 1020

DECLARE @orderedKeys TABLE (
  rownum int IDENTITY NOT NULL PRIMARY KEY CLUSTERED,
  TableKey int NOT NULL
)

SET ROWCOUNT @lastRecord
INSERT INTO @orderedKeys (TableKey) SELECT ID FROM Orders WHERE OrderDate >= '1980-01-01' ORDER BY OrderDate

SET ROWCOUNT 0

SELECT t.*
FROM Orders t
  INNER JOIN @orderedKeys o ON o.TableKey = t.ID
WHERE o.rownum >= @firstRecord
ORDER BY o.rownum

इस दृष्टिकोण को बहु-स्तंभ कुंजियों के साथ तालिकाओं तक बढ़ाया जा सकता है, और यह OR (जो सूचकांक उपयोग को छोड़ देता है) के उपयोग के प्रदर्शन को नहीं बढ़ाता है। नकारात्मक पक्ष यह है कि डेटा सेट बहुत बड़ा है और अंतिम पृष्ठ के पास है तो अस्थायी स्थान का उपयोग किया जाता है। मैंने उस मामले में कर्सर के प्रदर्शन का परीक्षण नहीं किया, लेकिन यह बेहतर हो सकता है।

ध्यान दें कि इस दृष्टिकोण को डेटा के पहले पृष्ठ के लिए अनुकूलित किया जा सकता है। इसके अलावा, ROWCOUNT का उपयोग किया गया था क्योंकि TOP SQL Server 2000 में एक चर को स्वीकार नहीं करता है।


3

Sql सर्वर 2012 में पेजिंग के लिए सबसे अच्छा तरीका है एक संग्रहीत प्रक्रिया में ऑफसेट और लाने के लिए उपयोग करना। OFFSET Keyword - अगर हम ऑफ़सेट को क्लॉज द्वारा ऑर्डर के साथ उपयोग करते हैं तो क्वेरी उन रिकॉर्ड की संख्या को छोड़ देगी जो हम OFFSET n Rows में निर्दिष्ट करते हैं।

FETCH NEXT कीवर्ड - जब हम नेक्स्ट के साथ Fetch Next का उपयोग करते हैं तो केवल एक क्रम के साथ यह आपके द्वारा पेजिंग में प्रदर्शित उन पंक्तियों को वापस कर देगा, जिन्हें बिना ऑफसेट के तो SQL एक त्रुटि उत्पन्न करेगा। इसका उदाहरण नीचे दिया गया है।

create procedure sp_paging
(
 @pageno as int,
 @records as int
)
as
begin
declare @offsetcount as int
set @offsetcount=(@pageno-1)*@records
select id,bs,variable from salary order by id offset @offsetcount rows fetch Next @records rows only
end

आप इसे फॉलो के रूप में निष्पादित कर सकते हैं।

exec sp_paging 2,3

2

SQL सर्वर साइड में क्वेरी के परिणाम को पृष्ठांकित करने के लिए ये मेरे समाधान हैं। ये दृष्टिकोण SQL Server 2008 और 2012 के बीच भिन्न हैं। इसके अलावा, मैंने एक कॉलम के साथ फ़िल्टरिंग और ऑर्डर की अवधारणा को जोड़ा है। यह बहुत ही कुशल है जब आप अपने ग्रिडव्यू में पेजिंग और फ़िल्टरिंग और ऑर्डर कर रहे हैं।

परीक्षण करने से पहले, आपको एक नमूना तालिका बनानी होगी और इस तालिका में कुछ पंक्ति सम्मिलित करनी होगी: (वास्तविक दुनिया में आपको अपने टेबल फ़ील्ड पर विचार करते हुए क्लॉज़ बदलना होगा और हो सकता है कि आपके पास चयन के मुख्य भाग में कुछ ज्वाइन और सबक्विरी हों)

Create Table VLT
(
    ID int IDentity(1,1),
    Name nvarchar(50),
    Tel Varchar(20)
)
GO


Insert INTO VLT
VALUES
    ('NAME' + Convert(varchar(10),@@identity),'FAMIL' + Convert(varchar(10),@@identity))
GO 500000

इन सभी नमूनों में, मैं प्रति पृष्ठ 200 पंक्तियों को क्वेरी करना चाहता हूं और मैं पृष्ठ संख्या 1200 के लिए पंक्ति ला रहा हूं।

SQL सर्वर 2008 में, आप CTE अवधारणा का उपयोग कर सकते हैं। उसकी वजह से, मैंने SQL सर्वर 2008+ के लिए दो प्रकार की क्वेरी लिखी है

- एसक्यूएल सर्वर 2008+

DECLARE @PageNumber Int = 1200
DECLARE @PageSize INT = 200
DECLARE @SortByField int = 1 --The field used for sort by
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/)
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information.

SELECT 
  Data.ID,
  Data.Name,
  Data.Tel
FROM
  (  
    SELECT 
      ROW_NUMBER() 
        OVER( ORDER BY 
                CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC'
                      THEN VLT.ID END ASC,
                CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC'
                      THEN VLT.ID END DESC,
                CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC'
                      THEN VLT.Name END ASC,
                CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC'
                      THEN VLT.Name END ASC,
                CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC'
                      THEN VLT.Tel END ASC,
                CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC'
                      THEN VLT.Tel END ASC
         ) AS RowNum
      ,*  
    FROM VLT 
    WHERE
      ( -- We apply the filter logic here
        CASE
          WHEN @FilterType = 'None' THEN 1

          -- Name column filter
          WHEN @FilterType = 'Contain' AND @FilterColumn = 1
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.ID LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 1
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.ID NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 1
            AND VLT.ID = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1
            AND VLT.ID <> @FilterValue THEN 1               

          -- Name column filter
          WHEN @FilterType = 'Contain' AND @FilterColumn = 2
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Name LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 2
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Name NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 2
            AND VLT.Name = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2
            AND VLT.Name <> @FilterValue THEN 1         

         -- Tel column filter   
         WHEN @FilterType = 'Contain' AND @FilterColumn = 3
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Tel LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 3
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Tel NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 3
            AND VLT.Tel = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3
            AND VLT.Tel <> @FilterValue THEN 1    

        END
      ) = 1   
  ) AS Data
WHERE Data.RowNum > @PageSize * (@PageNumber - 1)
  AND Data.RowNum <= @PageSize * @PageNumber
ORDER BY Data.RowNum

GO

और SQL Server 2008 में CTE के साथ दूसरा समाधान +

DECLARE @PageNumber Int = 1200
DECLARE @PageSize INT = 200
DECLARE @SortByField int = 1 --The field used for sort by
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/)
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information.

;WITH
  Data_CTE
  AS
  (  
    SELECT 
      ROW_NUMBER() 
        OVER( ORDER BY 
                CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC'
                      THEN VLT.ID END ASC,
                CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC'
                      THEN VLT.ID END DESC,
                CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC'
                      THEN VLT.Name END ASC,
                CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC'
                      THEN VLT.Name END ASC,
                CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC'
                      THEN VLT.Tel END ASC,
                CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC'
                      THEN VLT.Tel END ASC
         ) AS RowNum
      ,*  
    FROM VLT
    WHERE
      ( -- We apply the filter logic here
        CASE
          WHEN @FilterType = 'None' THEN 1

          -- Name column filter
          WHEN @FilterType = 'Contain' AND @FilterColumn = 1
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.ID LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 1
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.ID NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 1
            AND VLT.ID = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1
            AND VLT.ID <> @FilterValue THEN 1               

          -- Name column filter
          WHEN @FilterType = 'Contain' AND @FilterColumn = 2
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Name LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 2
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Name NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 2
            AND VLT.Name = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2
            AND VLT.Name <> @FilterValue THEN 1         

         -- Tel column filter   
         WHEN @FilterType = 'Contain' AND @FilterColumn = 3
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Tel LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 3
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Tel NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 3
            AND VLT.Tel = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3
            AND VLT.Tel <> @FilterValue THEN 1    

        END
      ) = 1     
  )

SELECT 
  Data.ID,
  Data.Name,
  Data.Tel
FROM Data_CTE AS Data
WHERE Data.RowNum > @PageSize * (@PageNumber - 1)
  AND Data.RowNum <= @PageSize * @PageNumber
ORDER BY Data.RowNum

- SQL सर्वर 2012+

DECLARE @PageNumber Int = 1200
DECLARE @PageSize INT = 200
DECLARE @SortByField int = 1 --The field used for sort by
DECLARE @SortOrder nvarchar(255) = 'ASC' --ASC or DESC
DECLARE @FilterType nvarchar(255) = 'None' --The filter type, as defined on the client side (None/Contain/NotContain/Match/NotMatch/True/False/)
DECLARE @FilterValue nvarchar(255) = '' --The value the user gave for the filter
DECLARE @FilterColumn int = 1 --The column to wich the filter is applied, represents the column number like when we send the information.

;WITH
  Data_CTE
  AS
  (  
    SELECT 
      *  
    FROM VLT
    WHERE
      ( -- We apply the filter logic here
        CASE
          WHEN @FilterType = 'None' THEN 1

          -- Name column filter
          WHEN @FilterType = 'Contain' AND @FilterColumn = 1
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.ID LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 1
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.ID NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 1
            AND VLT.ID = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 1
            AND VLT.ID <> @FilterValue THEN 1               

          -- Name column filter
          WHEN @FilterType = 'Contain' AND @FilterColumn = 2
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Name LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 2
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Name NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 2
            AND VLT.Name = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 2
            AND VLT.Name <> @FilterValue THEN 1         

         -- Tel column filter   
         WHEN @FilterType = 'Contain' AND @FilterColumn = 3
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Tel LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'NotContain' AND @FilterColumn = 3
            AND ( -- In this case, when the filter value is empty, we want to show everything.
                VLT.Tel NOT LIKE '%' + @FilterValue + '%'
               OR
                @FilterValue = ''
               ) THEN 1
          WHEN @FilterType = 'Match' AND @FilterColumn = 3
            AND VLT.Tel = @FilterValue THEN 1
          WHEN @FilterType = 'NotMatch' AND @FilterColumn = 3
            AND VLT.Tel <> @FilterValue THEN 1    

        END
      ) = 1         
  )

SELECT 
  Data.ID,
  Data.Name,
  Data.Tel
FROM Data_CTE AS Data
ORDER BY 
    CASE WHEN @SortByField = 1 AND @SortOrder = 'ASC'
        THEN Data.ID END ASC,
    CASE WHEN @SortByField = 1 AND @SortOrder = 'DESC'
        THEN Data.ID END DESC,
    CASE WHEN @SortByField = 2 AND @SortOrder = 'ASC'
        THEN Data.Name END ASC,
    CASE WHEN @SortByField = 2 AND @SortOrder = 'DESC'
        THEN Data.Name END ASC,
    CASE WHEN @SortByField = 3 AND @SortOrder = 'ASC'
        THEN Data.Tel END ASC,
    CASE WHEN @SortByField = 3 AND @SortOrder = 'DESC'
        THEN Data.Tel END ASC
OFFSET @PageSize * (@PageNumber - 1) ROWS FETCH NEXT @PageSize ROWS ONLY;

1

इस दृष्टिकोण का प्रयास करें:

SELECT TOP @offset a.*
FROM (select top @limit b.*, COUNT(*) OVER() totalrows 
        from TABLENAME b order by id asc) a
ORDER BY id desc;

1

केस वार का उपयोग करें निम्नलिखित उपयोग करने में आसान और तेज प्रतीत होता है। बस पेज नंबर सेट करें।

use AdventureWorks
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6;
with result as(
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail
where 1=1
)
select SalesOrderDetailID, SalesOrderID, ProductID from result
WHERE result.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)

बिना सीटीई के भी

use AdventureWorks
DECLARE @RowsPerPage INT = 10, @PageNumber INT = 6
SELECT SalesOrderDetailID, SalesOrderID, ProductID
FROM (
SELECT SalesOrderDetailID, SalesOrderID, ProductID,
ROW_NUMBER() OVER (ORDER BY SalesOrderDetailID) AS RowNum
FROM Sales.SalesOrderDetail
where 1=1
 ) AS SOD
WHERE SOD.RowNum BETWEEN ((@PageNumber-1)*@RowsPerPage)+1
AND @RowsPerPage*(@PageNumber)

1
1 = 1 क्या करता है सर?
एरोल पलेरासियो डे

0

वैसे मैंने अपने SQL 2000 डेटाबेस में निम्नलिखित नमूना क्वेरी का उपयोग किया है, यह SQL 2005 के लिए भी अच्छा काम करता है। यह आपके द्वारा दी जाने वाली शक्ति कई कॉलमों का उपयोग करके गतिशील रूप से आदेश देती है। मैं आपको बताता हूं ... यह शक्तिशाली है :)

    ALTER PROCEDURE [dbo].[RE_ListingReports_SelectSummary] 

@CompanyID  int,
@pageNumber     int,
@pageSize   int, 
@sort       varchar(200)
AS

DECLARE @sql nvarchar(4000)
DECLARE @strPageSize nvarchar(20)
DECLARE @strSkippedRows nvarchar(20)
DECLARE @strFields nvarchar(4000)
DECLARE @strFilter nvarchar(4000)
DECLARE @sortBy nvarchar(4000)
DECLARE @strFrom nvarchar(4000)
DECLARE @strID nvarchar(100)

If(@pageNumber < 0)
  SET @pageNumber = 1
SET @strPageSize = CAST(@pageSize AS varchar(20)) 
SET @strSkippedRows = CAST(((@pageNumber - 1) * @pageSize) AS varchar(20))-- For    example if pageNumber is 5  pageSize is 10, then SkippedRows = 40.
SET @strID = 'ListingDbID'
SET @strFields = 'ListingDbID,
ListingID,  
[ExtraRoom]
'
SET @strFrom = ' vwListingSummary '

SET @strFilter = ' WHERE
        CompanyID = ' + CAST(@CompanyID As varchar(20)) 
End
SET @sortBy = ''
if(len(ltrim(rtrim(@sort))) > 0)
SET @sortBy = ' Order By ' + @sort

-- Total Rows Count

SET @sql =  'SELECT Count(' + @strID + ')  FROM ' + @strFROM + @strFilter
EXEC sp_executesql @sql

--// This technique is used in a Single Table pagination
SET @sql = 'SELECT ' + @strFields + ' FROM ' + @strFROM +
    ' WHERE ' + @strID +  ' IN ' + 
   '  (SELECT TOP ' + @strPageSize + ' ' + @strID + ' FROM ' + @strFROM + @strFilter + 
             ' AND  ' + @strID + ' NOT IN ' + '
          (SELECT TOP ' + @strSkippedRows + ' ' + @strID + ' FROM ' + @strFROM + @strFilter + @SortBy + ') ' 
   + @SortBy + ') ' + @SortBy
Print @sql 
EXEC sp_executesql @sql

सबसे अच्छा हिस्सा है sp_executesql कैश बाद में कॉल करता है, बशर्ते आप एक ही पैरामीटर पास करें यानी एक ही sql टेक्स्ट जनरेट करें।


0
   CREATE view vw_sppb_part_listsource as 
    select row_number() over (partition by sppb_part.init_id order by sppb_part.sppb_part_id asc ) as idx, * from (
      select 
          part.SPPB_PART_ID
          , 0 as is_rev
          , part.part_number 
          , part.init_id 
      from t_sppb_init_part part 
      left join t_sppb_init_partrev prev on ( part.SPPB_PART_ID = prev.SPPB_PART_ID )
      where prev.SPPB_PART_ID is null 
      union 
      select 
          part.SPPB_PART_ID
          , 1 as is_rev
          , prev.part_number 
          , part.init_id 
      from t_sppb_init_part part 
      inner join t_sppb_init_partrev prev on ( part.SPPB_PART_ID = prev.SPPB_PART_ID )
    ) sppb_part

जब यह अलग init_id की बात आती है तो idx को पुनः आरंभ करेगा


0

के लिए ROW_NUMBERतकनीक, यदि आप उपयोग करने के लिए एक छँटाई स्तंभ की जरूरत नहीं है, तो आप उपयोग कर सकते हैं CURRENT_TIMESTAMPइस प्रकार है:

SELECT TOP 20 
    col1,
    col2,
    col3,
    col4
FROM (
    SELECT 
         tbl.col1 AS col1
        ,tbl.col2 AS col2
        ,tbl.col3 AS col3
        ,tbl.col4 AS col4
        ,ROW_NUMBER() OVER (
            ORDER BY CURRENT_TIMESTAMP
            ) AS sort_row
    FROM dbo.MyTable tbl
    ) AS query
WHERE query.sort_row > 10
ORDER BY query.sort_row

इसने मेरे लिए 700,000 तक की तालिका आकारों की खोजों के लिए अच्छा काम किया है।

यह भ्रूण 11 से 30 रिकॉर्ड करता है।


एक अच्छे अभ्यास के रूप में, पृष्ठांकन के साथ आपको परिणाम के सेट में स्तंभों के अनूठे सेट से ऑर्डर करने का प्रयास करना चाहिए क्योंकि ऑर्डर की गारंटी नहीं दी जानी चाहिए।
टेलर

2
यह
भ्रूण

0
create PROCEDURE SP_Company_List (@pagesize int = -1 ,@pageindex int= 0   ) > AS BEGIN  SET NOCOUNT ON;


    select  Id , NameEn     from Company  ORDER by Id ASC  
OFFSET (@pageindex-1 )* @pagesize   ROWS FETCH NEXt @pagesize ROWS ONLY END  GO

DECLARE   @return_value int

EXEC  @return_value = [dbo].[SP_Company_List]         @pagesize = 1 ,         > @pageindex = 2

SELECT    'Return Value' = @return_value

GO

0

यह बिट आपको SQL सर्वर, और MySQL के नए संस्करणों का उपयोग करके पेजेट करने की क्षमता देता है और हर पंक्ति में पंक्तियों की कुल संख्या को वहन करता है। अद्वितीय पंक्तियों की संख्या की गणना करने के लिए अपनी महत्वपूर्ण कुंजी का उपयोग करता है।

WITH T AS
(  
  SELECT TABLE_ID, ROW_NUMBER() OVER (ORDER BY TABLE_ID) AS RN
  , (SELECT COUNT(TABLE_ID) FROM TABLE) AS TOTAL 
  FROM TABLE (NOLOCK)
)

SELECT T2.FIELD1, T2.FIELD2, T2.FIELD3, T.TOTAL 
FROM TABLE T2 (NOLOCK)
INNER JOIN T ON T2.TABLE_ID=T.TABLE_ID
WHERE T.RN >= 100
AND T.RN < 200

क्या आप कृपया कोई टिप्पणी छोड़ सकते हैं जो यह बताए कि आपका कोड क्या करता है?
डग एफ

0

यह 2012 पुराने एसओ प्रश्न का एक डुप्लिकेट है: पेजिंग को लागू करने का कुशल तरीका

[TableX] ORDER से [फील्डएक्स] OFFSET 500 ROWS FETCH NEXT 100 ROWS केवल

यहाँ इस विषय पर अधिक विवरण में और वैकल्पिक दृष्टिकोणों के साथ चर्चा की गई है।


0

2012 के बाद से हम उपयोग कर सकते हैं OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY


-19

आपने भाषा निर्दिष्ट नहीं की और न ही आप किस ड्राइवर का उपयोग कर रहे हैं। इसलिए मैं इसका सारगर्भित वर्णन कर रहा हूं।

  • स्क्रॉल करने योग्य परिणाम / डेटासेट बनाएं। इसके लिए मेज पर प्राथमिक होना आवश्यक है
  • अंत तक कूदो
  • पंक्ति गणना का अनुरोध करें
  • पृष्ठ के प्रारंभ में कूदें
  • पृष्ठ के अंत तक पंक्तियों के माध्यम से स्क्रॉल करें
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.