Frage

Was ist die beste Art und Weise (Leistung klug) Ergebnisse in SQL Server 2000 Paginieren, 2005, 2008, 2012, wenn Sie auch die Gesamtzahl der Ergebnisse erhalten möchten (vor Paginieren)?

War es hilfreich?

Lösung

Getting die Gesamtzahl der Ergebnisse und Paginierung sind zwei unterschiedliche Vorgänge. Aus Gründen der diesem Beispiel nehmen wir an, dass die Abfrage Sie es zu tun ist

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

In diesem Fall würden Sie die Gesamtzahl der Ergebnisse bestimmen mit:

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

... was ineffizient zu sein scheint, aber es ist eigentlich ziemlich performant, alle Indizes usw. unter der Annahme richtig eingerichtet sind.

Als nächstes wird auf die tatsächlichen Ergebnisse zurück in einer ausgelagerten Art und Weise zu erhalten, die folgende Abfrage wäre höchst effizient:

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

Dies wird wieder Zeilen 1-19 der ursprünglichen Abfrage. Die kühle Sache hier, vor allem für Web-Anwendungen, ist, dass Sie keinen Zustand zu halten haben, mit Ausnahme der Zeilennummern zurückgegeben werden.

Andere Tipps

Schließlich Microsoft SQL Server 2012 veröffentlicht wurde, ich mag seine Einfachheit für eine Paginierung wirklich, Sie müssen nicht komplexe Abfragen verwenden wie hier beantwortet.

Für die nächsten 10 Zeilen immer nur diese Abfrage ausführen:

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

http://technet.microsoft.com/en-us/library/ gg699618.aspx
Wichtige Punkte zu berücksichtigen, wenn es mit:

  • ist ORDER BY zwingend verwenden Klausel OFFSET und FETCH.
  • OFFSET-Klausel ist obligatorisch bei FETCH. Sie können nie verwenden, ORDER BY ... FETCH.
  • TOP kann nicht mit OFFSET kombiniert werden und in der gleichen Abfrage FETCH Ausdruck.

Unglaublich, hat keine andere Antwort erwähnt die schnellsten Art und Weise Paginierung in all SQL Server-Versionen zu tun. Versätze kann schrecklich langsam für große Seitenzahlen wie hier gebenchmarkt ist. Es ist ein ganz anderer, viel schneller Weg Paginierung in SQL auszuführen. Dies wird oft als das „Suchverfahren“ oder „Keyset Paginierung“ genannt, wie in dieses Blog-Post hier .

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

Die "suchen Prädikat"

Die @previousScore und @previousPlayerId Werte sind die jeweiligen Werte des letzten Datensatzes von der vorherigen Seite. Auf diese Weise können Sie die „nächste“ Seite holen. Wenn die ORDER BY Richtung ASC ist, verwenden Sie einfach > statt.

Mit dem obigen Verfahren können Sie nicht sofort auf Seite 4 springen, ohne zuerst die vorherigen 40 Datensätze geholt zu haben. Aber oft wollen Sie nicht so weit sowieso springen. Stattdessen erhalten Sie eine viel schnellere Abfrage, die auf Ihrer Indizierung abhängig Möglicherweise können Daten in konstanter Zeit holen. Plus Ihre Seiten bleiben „stabil“, unabhängig davon, ob die zugrunde liegenden Datenänderungen (zum Beispiel auf Seite 1, während Sie auf Seite 4).

Dies ist der beste Weg, Paginierung zu implementieren, wenn ein träges Laden mehr Daten in Web-Anwendungen, zum Beispiel.

Hinweis: das "Suchverfahren" auch genannt Keyset Paginierung .

Gesamtzahl Datensätze vor Paginierung

Die COUNT(*) OVER() Fensterfunktion wird Ihnen helfen, die Gesamtzahl der Datensätze „vor Paginierung“ zu zählen. Wenn Sie SQL Server 2000 verwenden, müssen Sie für die COUNT(*) zu zwei Abfragen zurückgreifen.

Von SQL Server 2012 können wir OFFSET und FETCH NEXT Klausel zu erreichen, um die Paginierung verwenden.

Versuchen Sie dieses, für SQL Server:

  

In dem SQL Server 2012 ein neues Feature wurde in der ORDER BY-Klausel hinzugefügt,   Optimierung eines Satzes Daten abzufragen, die Arbeit leichter mit Daten machen   Paging für jedermann, auch für die gesamte Ausführung in T-SQL schreibt   Plan in SQL Server.

     

Unter dem T-SQL-Skript mit der gleichen Logik in den vorherigen verwendet   Beispiel.

--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: Rufen einer Abfrage mit SQL Server

Es gibt eine gute Übersicht über verschiedene Paging-Techniken unter http: //www.codeproject .com / KB / aspnet / PagingLarge.aspx

Ich habe verwendet ROWCOUNT Methode recht häufig vor allem mit SQL Server 2000 (wird auch mit 2005 & 2008 arbeiten, nur Leistung messen im Vergleich zu ROW_NUMBER), dann ist es blitzschnell, aber Sie müssen sicherstellen, dass die sortierten Spalte (n) haben (meist) eindeutige Werte.

MSDN: ROW_NUMBER (Transact-SQL)

  

Gibt die laufende Nummer einer Zeile innerhalb einer Partition eines Ergebnismenge in jeder Partition auf 1 für die erste Reihe zu starten.

     

Das folgende Beispiel gibt Zeilen mit Nummern 50 bis 60 einschließlich in der Reihenfolge des Bestelldatums.

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

Für SQL Server 2000 können Sie ROW_NUMBER simulieren () unter Verwendung einer Tabellenvariable mit einer Identity-Spalte:

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

Dieser Ansatz kann mit mehrspaltigen Schlüssel zu den Tabellen erweitert werden, und es nicht die Performance-Overhead der Verwendung von OR entstehen (die Indexnutzung überspringt). Der Nachteil ist die Menge an temporärer Speicherplatz verbraucht, wenn der Datensatz sehr groß ist und man ist in der Nähe der letzten Seite. Ich habe nicht Cursor Leistung in diesem Fall testen, aber es könnte besser sein.

Beachten Sie, dass dieser Ansatz für die erste Seite von Daten optimiert werden kann. Auch wurde ROWCOUNT seit TOP verwendet keine Variable in SQL Server 2000 übernehmen.

Der beste Weg für das Paging in SQL Server 2012 ist durch Verwendung von Versatz und als nächstes in einer gespeicherten Prozedur abzurufen. OFFSET Schlüsselwort -. Wenn wir mit dem Auftrag durch Klausel Offset verwenden dann die Abfrage die Anzahl der Datensätze wir angegeben in OFFSET n Zeilen überspringen

FETCH NEXT-Keywords - Wenn wir Next by-Klausel mit einer Bestellung Fetch verwenden nur, es wird wieder die Anzahl der Zeilen, die Sie in Paging angezeigt werden soll, ohne Offset dann SQL wird ein Fehler generiert. hier ist das Beispiel weiter unten.

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

Sie können es wie folgt ausgeführt werden.

exec sp_paging 2,3

Das sind meine Lösungen für das Ergebnis der Abfrage in SQL Server-Seite Paging. Diese Ansätze sind unterschiedlich zwischen SQL Server 2008 und 2012. Außerdem habe ich das Konzept der Filterung und Ordnung, indem sie mit einer Spalte hinzugefügt. Es ist sehr effizient, wenn Sie das Paging und Filterung und Ordnung in Ihrem Gridview sind.

Vor dem Testen Sie haben eine Beispieltabelle erstellen und eine Zeile in dieser Tabelle einfügen: (In der realen Welt müssen Sie ändern Where-Klausel Ihre Tabellenfelder unter Berücksichtigung und vielleicht haben Sie einige beitreten und Unterabfrage in Hauptteil wählen)

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

In all dieser Probe, möchte ich 200 Zeilen pro Seite abfragen und ich bin Abrufen der Zeile für Seitennummer 1200.

In SQL Server 2008 können Sie das CTE-Konzept verwenden. Aus diesem Grunde habe ich zwei Arten von Abfrage für SQL Server geschrieben 2008 +

- SQL Server 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

Und zweite Lösung mit CTE in SQL Server 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.

;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 Server 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;

Versuchen Sie diesen Ansatz:

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

Use Case wiese folgendes scheint einfach zu sein gesetzt zu bedienen und schnell nur die Seitenzahl.

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)

auch mit CTE

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)

Nun, ich die folgende Beispielabfrage in meiner SQL 2000-Datenbank verwendet haben, funktioniert es gut für SQL zu 2005. Die Macht es Sie gibt, ist dynamisch, um durch mehrere Spalten. Ich sage dir ... das ist mächtig :)

    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

Der beste Teil ist Sp_executesql Caches später Anrufe, sofern Sie dieselben Parameter übergeben d.h gleiche SQL-Text zu generieren.

   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

wird idx neu starten, wenn es um andere init_id kommt

Für die ROW_NUMBER Technik, wenn Sie nicht über eine Sortierspalte verwenden müssen, können Sie die CURRENT_TIMESTAMP wie folgt:

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

Das hat gut für mich gearbeitet für die Suche über Tischgrößen von sogar bis 700.000 auf.

Dies holt Datensätze 11 bis 30.

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

Dieses Bit gibt Ihnen Fähigkeit, SQL Server Paginieren verwenden und neuere Versionen von MySQL und trägt die Gesamtzahl der Zeilen in jeder Zeile. Verwendet Ihren pimary Schlüssel Anzahl der eindeutigen Zeilen zu zählen.

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

Sie haben nicht die Sprache angeben, noch welche Treiber Sie verwenden. Ich beschreibe es daher abstrakt.

  • Erstellen Sie eine scrollbare resultset / Datensatz. Dies erforderte eine primäre auf dem Tisch (e)
  • Sprung zum Ende
  • fordern Sie die Zeilenanzahl
  • Sprung zum Anfang der Seite
  • blättert durch die Reihen bis zum Ende der Seite
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top