Implementieren Sie mit dieser Abfrage die Paging-Funktion (Überspringen / Nehmen)

138

Ich habe versucht, ein wenig darüber zu verstehen, wie benutzerdefiniertes Paging in SQL implementiert wird, zum Beispiel Artikel wie diesen zu lesen .

Ich habe die folgende Abfrage, die perfekt funktioniert. Aber ich möchte Paging mit diesem implementieren.

SELECT TOP x PostId FROM ( SELECT PostId, MAX (Datemade) as LastDate
 from dbForumEntry 
 group by PostId ) SubQueryAlias
 order by LastDate desc

Was will ich?

Ich habe Forenbeiträge mit verwandten Einträgen. Ich möchte die Beiträge mit den zuletzt hinzugefügten Einträgen erhalten, damit ich die kürzlich diskutierten Beiträge auswählen kann.

Jetzt möchte ich in der Lage sein, die "Top 10 bis 20 kürzlich aktiven Beiträge" anstelle von "Top 10" zu erhalten.

Was habe ich versucht?

Ich habe versucht, die ROW-Funktionen wie im Artikel zu implementieren, aber wirklich ohne Glück.

Irgendwelche Ideen, wie man es umsetzt?

Lars Holdgaard
quelle

Antworten:

288

In SQL Server 2012 ist das sehr, sehr einfach

SELECT col1, col2, ...
 FROM ...
 WHERE ... 
 ORDER BY -- this is a MUST there must be ORDER BY statement
-- the paging comes here
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

Wenn wir ORDER BY überspringen möchten, können wir verwenden

SELECT col1, col2, ...
  ...
 ORDER BY CURRENT_TIMESTAMP
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

(Ich würde das lieber als Hack markieren - aber es wird verwendet, z. B. von NHibernate. Die Verwendung einer mit Bedacht aufgenommenen Spalte als ORDER BY wird bevorzugt.)

um die Frage zu beantworten:

--SQL SERVER 2012
SELECT PostId FROM 
        ( SELECT PostId, MAX (Datemade) as LastDate
            from dbForumEntry 
            group by PostId 
        ) SubQueryAlias
 order by LastDate desc
OFFSET 10 ROWS -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

Neue Schlüsselwörter offsetund fetch next(nur nach SQL-Standards) wurden eingeführt.

Aber ich denke, dass Sie SQL Server 2012 nicht verwenden , oder ? In der vorherigen Version ist es ein bisschen (ein bisschen) schwierig. Hier finden Sie Vergleiche und Beispiele für alle SQL Server-Versionen: hier

Dies könnte also in SQL Server 2008 funktionieren :

-- SQL SERVER 2008
DECLARE @Start INT
DECLARE @End INT
SELECT @Start = 10,@End = 20;


;WITH PostCTE AS 
 ( SELECT PostId, MAX (Datemade) as LastDate
   ,ROW_NUMBER() OVER (ORDER BY PostId) AS RowNumber
   from dbForumEntry 
   group by PostId 
 )
SELECT PostId, LastDate
FROM PostCTE
WHERE RowNumber > @Start AND RowNumber <= @End
ORDER BY PostId
Radim Köhler
quelle
Vielen Dank! Das ist eine wirklich gute Antwort! Einzige Frage zum SQL 2008. Ich möchte, dass ORDER BY vor WHERE erfolgt, da derzeit die Teilmenge sortiert wird, aber wir möchten etwas aus der gesamten Menge auswählen ... Irgendwelche Ideen? :) Nochmals
vielen
2
Wenn ich Sie richtig verstehe, möchten Sie nach LastDate sortieren, oder? dann können wir die OVER () -Klausel folgendermaßen ändern: ROW_NUMBER () OVER (ORDER BY MAX (Datemade) desc ). Und entfernen Sie die letzte ORDER BY PostId . Jetzt sollte der CTE nach Bedarf "früher" sortiert werden. richtig?
Radim Köhler
1
Vielen Dank, dass dies geholfen hat. Ein Hinweis zum Beispiel für 2012, Reihenfolge nach ist obligatorisch. Ich habe dies ohne Klausel nach Reihenfolge nach versucht und den Fehler "Falsche Syntax" erhalten. Ich hatte keine Ahnung, was falsch war, bis ich mir die MSDN-Syntax angesehen und festgestellt habe, dass die Reihenfolge nach obligatorisch ist .
Esen
Ist die erste Zeile 1 oder 0? Sollte das WO sein WHERE RowNumber >= @Start AND RowNumber < @End, um die ersten 1000 Zeilen zu erhalten, wenn @Start0 und @End1000 ist?
CWSpear
1
Vielen Dank
Mafii
5
OFFSET     10 ROWS       -- skip 10 rows
FETCH NEXT 10 ROWS ONLY; -- take 10 rows

Verwenden Sie dies am Ende Ihrer ausgewählten Syntax. =)

Nicolas Vinícius Sroczynski
quelle
5

SQL 2008

Radim Köhlers Antwort funktioniert, aber hier ist eine kürzere Version:

select top 20 * from
(
select *,
ROW_NUMBER() OVER (ORDER BY columnid) AS ROW_NUM
from tablename
) x
where ROW_NUM>10

Quelle: https://forums.asp.net/post/4033909.aspx

Tadej
quelle
-1

Sie können verschachtelte Abfragen für die Paginierung wie folgt verwenden:

Paging von 4 bis 8 Row Row , wo CustomerId ist Primärschlüssel .

SELECT Top 5 * FROM Customers
WHERE Country='Germany' AND CustomerId Not in (SELECT Top 3 CustomerID FROM Customers
WHERE Country='Germany' order by city) 
order by city;
amoljdv06
quelle