2009-03-02 5 views
85

Ich habe diese Abfrage mit Mysql:Wie implementiert man LIMIT mit Microsoft SQL Server?

select * from table1 LIMIT 10,20 

Wie kann ich dies tun, mit Microsoft SQL?

+0

möglich duplicate von [LIMIT 10..20 in SQL Server] (http://stackoverflow.com/questions/971964/limit-10-20-in-sql-server) – assylias

+10

Da diese Frage zuerst gestellt wurde, würde Ist die andere Frage das Duplikat? –

+0

Siehe: [Sollte ich eine Frage als Duplikat kennzeichnen, wenn sie bessere Antworten erhalten hat?] (Https://meta.stackoverflow.com/q/251938/55075) – kenorb

Antwort

94

Starten von SQL Server 2005 können Sie dies tun ...

USE AdventureWorks; 
GO 
WITH OrderedOrders AS 
(
    SELECT SalesOrderID, OrderDate, 
    ROW_NUMBER() OVER (ORDER BY OrderDate) AS 'RowNumber' 
    FROM Sales.SalesOrderHeader 
) 
SELECT * 
FROM OrderedOrders 
WHERE RowNumber BETWEEN 10 AND 20; 

oder so etwas wie dies für das Jahr 2000 und unter Versionen ...

SELECT TOP 10 * FROM (SELECT TOP 20 FROM Table ORDER BY Id) ORDER BY Id DESC 
+5

Die zweite Abfrage schlägt fehl, wenn Sie z. 14 Zeilen in der Tabelle. Es gibt Ihnen Zeilen 5 bis 14, aber Sie möchten Zeilen 11 bis 14. Im Allgemeinen schlägt es für die letzte "Seite" eines Ergebnisses fehl, es sei denn, die Gesamtzeilen sind ein Vielfaches dieser "Seiten" -Größe. –

+0

Du hast Recht ... habe es nicht getestet :) –

+84

So eine einfache Sache muss von MS noch einmal so schwer gemacht werden! – Martin

-6
SELECT TOP 10 * FROM table; 

ist die gleiche wie

SELECT * FROM table LIMIT 0,10; 

Here's an article about implementing Limit in MsSQL Es ist ein schönes Lese, speziell die Kommentare.

+1

Danke, aber ich möchte den Datensatz zwischen 10 und 20, da ist's eine Möglichkeit, es zu tun? – Bigballs

+1

Diese _only ever_ bekommt die Zeilen vom Anfang der Ergebnismenge ... –

+2

Diese Antwort antwortet nicht auf die Ursprungsfrage, aber es ist nützlich, wenn jemand wie ich wissen muss, wie man die ersten N Ergebnisse bekommt und hier angekommen ist über Google etc ... – brianlmerritt

41

Klob, aber es wird funktionieren.

SELECT TOP 10 * FROM table WHERE id NOT IN (SELECT TOP 10 id FROM table ORDER BY id) FROM table ORDER BY id 

MSSQLs Weglassung einer LIMIT-Klausel ist kriminell, IMO. Sie sollten diese Art von kludgy Workaround nicht machen müssen.

+0

Haben Sie einen anderen Vorschlag, um dies zu umgehen? – Bigballs

+0

Ich habe beim letzten Mal viel gegoogelt, als ich mit MSSQL umgehen musste und das war die beste Lösung, die ich gefunden habe. Nicht angenehm, aber es funktioniert. – ceejayoz

+0

Diese Lösung funktioniert nur, wenn die Ergebnismenge eine Spalte enthält, die eindeutig ist. Es ist keine allgemeine Lösung, um LIMIT für irgendeine Abfrage nachzuahmen. –

-2

Wenn ich mich richtig erinnere (es war ein während, da ich mit SQL Server getupft) Sie in der Lage sein können, so etwas zu verwenden: (2005 und bis)

SELECT 
    * 
    ,ROW_NUMBER() OVER(ORDER BY SomeFields) AS [RowNum] 
FROM SomeTable 
WHERE RowNum BETWEEN 10 AND 20 
+0

SQL Server 2012: Msg 207, Ebene 16, Status 1, Zeile 5 Ungültiger Spaltenname 'RowNum'. –

+0

klingt, als hätten Sie irgendwo einen Tippfehler in Ihrer Aussage. RowNum ist der Name, den wir dem Ausdruck zuweisen. Stellen Sie Ihr Problem mit der Quelle und die Gemeinschaft wird Ihnen helfen – Kris

+0

Dies ist keine gültige Syntax. Sie können nicht in 'WHERE' einen Alias ​​referenzieren, der in der SELECT-Klausel der gleichen Ebene definiert ist. –

18

Dies ist al die meisten ein Duplikat einer Frage, fragte ich im Oktober: Emulate MySQL LIMIT clause in Microsoft SQL Server 2000

Wenn Sie Microsoft SQL Server 2000 verwenden, gibt es keine gute Lösung. Die meisten Personen müssen das Ergebnis der Abfrage in einer temporären Tabelle mit einem Primärschlüssel IDENTITY erfassen. Dann Abfrage gegen die Primärschlüsselspalte mit einer BETWEEN Bedingung.

Wenn Sie Microsoft SQL Server 2005 oder höher verwenden, haben Sie eine ROW_NUMBER()-Funktion, so dass Sie das gleiche Ergebnis erhalten können, aber vermeiden Sie die temporäre Tabelle.

SELECT t1.* 
FROM (
    SELECT ROW_NUMBER OVER(ORDER BY id) AS row, t1.* 
    FROM (...original SQL query...) t1 
) t2 
WHERE t2.row BETWEEN @offset+1 AND @[email protected]; 

Sie können dies auch als common table expression schreiben als answer in @Leon Tayson ist gezeigt.

+0

ROW_NUMBER() OVER (ORDER BY) erhält Punkte, um in ANSI SQL: 2003 gültig zu sein, obwohl die Unterstützung in anderen DBMS als SQL Server sehr fleckig ist. Und es ist natürlich ziemlich klobig ... – bobince

+0

@bobince: Es stellt sich heraus, dass Oracle, Microsoft SQL Server 2005, IBM DB2 und PostgreSQL 8.4 alle Fensterfunktionen unterstützen. Das deckt einen großen Teil des SQL-Marktes ab. Die Unterstützung ist nur spotty, wenn Sie MySQL, SQLite oder eine alte Version der DB oben verwenden. –

11
SELECT * 
FROM (
     SELECT TOP 20 
       t.*, ROW_NUMBER() OVER (ORDER BY field1) AS rn 
     FROM table1 t 
     ORDER BY 
       field1 
     ) t 
WHERE rn > 10 
+0

Nun, ich habe gerade überprüft, SQL Server erwies sich als klug genug, um auf ROW_NUMBER() Bedingungen zu stoppen, wenn es eine indizierte Spalte in der ORDER BY-Klausel gibt. – Quassnoi

1

Dies ist ein mehrstufiger Ansatz, der in SQL2000 funktioniert.

-- Create a temp table to hold the data 
CREATE TABLE #foo(rowID int identity(1, 1), myOtherColumns) 

INSERT INTO #foo (myColumns) SELECT myData order By MyCriteria 

Select * FROM #foo where rowID > 10 
8

syntaktisch MySQL LIMIT Abfrage ist so etwas:

SELECT * FROM table LIMIT OFFSET, ROW_COUNT 

Diese wie

in Microsoft SQL Server übersetzt werden kann
SELECT * FROM 
(
    SELECT TOP #{OFFSET+ROW_COUNT} *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table 
) a 
WHERE rnum > OFFSET 

Jetzt select * from table1 LIMIT 10,20 Ihre Abfrage wie folgt sein:

SELECT * FROM 
(
    SELECT TOP 30 *, ROW_NUMBER() OVER (ORDER BY (SELECT 1)) AS rnum 
    FROM table1 
) a 
WHERE rnum > 10 
1
SELECT 
    * 
FROM 
    (
     SELECT 
      top 20    -- ($a) number of records to show 
      * 
     FROM 
      (
       SELECT 
        top 29  -- ($b) last record position 
        * 
       FROM 
        table  -- replace this for table name (i.e. "Customer") 
       ORDER BY 
        2 ASC 
      ) AS tbl1 
     ORDER BY 
      2 DESC 
    ) AS tbl2 
ORDER BY 
    2 ASC; 

-- Examples: 

-- Show 5 records from position 5: 
-- $a = 5; 
-- $b = (5 + 5) - 1 
-- $b = 9; 

-- Show 10 records from position 4: 
-- $a = 10; 
-- $b = (10 + 4) - 1 
-- $b = 13; 

-- To calculate $b: 
-- $b = ($a + position) - 1 

-- For the present exercise we need to: 
-- Show 20 records from position 10: 
-- $a = 20; 
-- $b = (20 + 10) - 1 
-- $b = 29; 
+0

War eine großartige Lösung für mich. – Tyde

2

Dies ist einer der Gründe, warum ich versuche, MS Server zu vermeiden ... aber trotzdem.Manchmal hast du einfach keine Option (yei! Und ich muss eine veraltete Version verwenden !!).

Mein Vorschlag ist, eine virtuelle Tabelle zu erstellen:

Von:

SELECT * FROM table 

An:

CREATE VIEW v_table AS  
    SELECT ROW_NUMBER() OVER (ORDER BY table_key) AS row,* FROM table 

Dann nur Abfrage:

SELECT * FROM v_table WHERE row BETWEEN 10 AND 20 

Wenn Felder hinzugefügt werden oder entfernt, "Zeile" ist automatisch aktualisiert

Das Hauptproblem mit dieser Option ist, dass ORDER BY behoben ist. Wenn Sie also eine andere Reihenfolge wünschen, müssen Sie eine andere Ansicht erstellen.

UPDATE

Es gibt ein weiteres Problem bei diesem Ansatz: wenn Sie versuchen, Ihre Daten zu filtern, wird es nicht wie erwartet funktionieren. Zum Beispiel, wenn Sie das tun:

SELECT * FROM v_table WHERE field = 'test' AND row BETWEEN 10 AND 20 

WHERE auf diese Daten beschränkt wird, die zwischen 10 und 20 (statt der Suche im gesamten Datensatz und die Begrenzung der Ausgabe) in den Reihen sind.

16

Beginnend mit SQL Server 2012 können Sie die OFFSET verwenden Klausel FETCH:

USE AdventureWorks; 
GO 
SELECT SalesOrderID, OrderDate 
FROM Sales.SalesOrderHeader 
ORDER BY SalesOrderID 
    OFFSET 10 ROWS 
    FETCH NEXT 10 ROWS ONLY; 
GO 

http://msdn.microsoft.com/en-us/library/ms188385(v=sql.110).aspx

Dies kann nicht richtig funktionieren, wenn die Bestellung durch nicht eindeutig ist.

Wenn die Abfrage zu ORDER BY OrderDate geändert wird, ist die zurückgegebene Ergebnismenge nicht wie erwartet. Diese

+0

Verwenden von 'mit' benötigt nur die Hälfte der Zeit, um die Abfrage zu beenden - siehe die Antwort von @Leon Tayson. Ich habe keine Ahnung, was Microsoft getan hat, um es so langsam zu machen. – isHuman

+0

Warum ist das nicht die akzeptierte Antwort? Wir sind in ** 2018 ** für das Schreien! – Skipper

8

ist, wie ich die Ergebnisse in MS SQL Server begrenzen 2012

SELECT * 
FROM table1 
ORDER BY columnName 
    OFFSET 10 ROWS FETCH NEXT 10 ROWS ONLY 

HINWEIS: OFFSET kann nur mit oder im Tandem verwendet werden, indem zu bestellen.

Um die Codezeile OFFSET xx ROWS FETCH NEXT-yy ROW NUR

Die „xx“ ist die Aufzeichnung/Zeilennummer, die Sie aus der Tabelle ziehen beginnen soll erklären.
IE: Wenn 40 Datensätze in Tabelle 1 vorhanden sind. Der obige Code wird aus Zeile 10 gezogen.

Das "yy" ist die Anzahl der Datensätze/Zeilen, die Sie aus der Tabelle ziehen möchten.
Um auf dem vorherigen Beispiel aufzubauen.
IE: Wenn Tabelle 1 40 Datensätze hat und Sie begannen, aus Zeile 10 zu ziehen und den NEXT-Satz von 10 (yy) zu nehmen.
Das würde bedeuten, oberhalb der Code die Datensätze aus Tabelle 1 ab Zeile 10 und endend bei 20 ziehen Somit Reihen ziehen 10 - 20.

Überprüfen Sie den Link für weitere Informationen heraus OFFSET

0

In SQL Es gibt kein LIMIT-Schlüsselwort.Wenn Sie nur eine begrenzte Anzahl von Zeilen benötigen, sollten Sie ein TOP-Schlüsselwort verwenden, das einem LIMIT ähnelt.

Verwandte Themen