2015-06-22 2 views
7

Ich möchte OFFSET und Fetch in meinem SQL Server 2012 Query.But ohne Reihenfolge von.Ich kann Reihenfolge nicht verwenden.Bein, weil meine Sortierreihenfolge verloren gehen wird. Wie kann ich OFFSET und Fetch ohne Reihenfolge und Zeilennummer und wo in meiner Abfrage verwenden? Meine 2 Auswahltabellen haben dieselbe Struktur.Wie Verwenden von OFFSET und Fetch ohne Reihenfolge von in SQL Server

INSERT INTO @TempTable [some columns] 
select [some columns] from table1 order by col1 
INSERT INTO @TempTable [same columns] 
select [some columns] from table2 order by col2 
select * from @TempTable OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY 

Diese Abfrage hat Syntaxfehler bei OFFSET-Schlüsselwort.

+3

'OFFSET-FETCH' nur angewandt wird, auf * geordneten * Sets. In einer SQL-Tabelle gibt es keine inhärente Reihenfolge und Sie * müssen * ORDER BY verwenden, wenn Sie einen angeben möchten. Was Sie also wollen, ist einfach nicht möglich. –

+0

Kann ich Bestellung von 1 verwenden? –

+2

Ja, natürlich, obwohl ich nicht verstehe, was du mit * meinst, weil meine Sortierreihenfolge verloren geht *. Es gibt keine inhärente Sortierreihenfolge in der Tabelle, die verloren gehen soll. –

Antwort

6

eine Identitätsspalte auf die temporäre Tabelle variable

declare @TempTable table([some columns], rownr int identity(1,1)) 

    INSERT INTO @TempTable [some columns] 
    select [some columns] from table1 order by col1 

    INSERT INTO @TempTable [same columns] 
    select [some columns] from table2 order by col2 

Eine automatische Inkrementieren Nummer wird für jede Zeile, in dem durch Zugabe hinzugefügt, in der sie zu der temporären Tabelle hinzugefügt werden. Die Einsätze müssen diese Spalte nicht ausfüllen, sodass die Einsätze so bleiben können, wie sie sind. Die Identitätsspalte kann dann für den Auftrag verwendet werden von:

select * from @TempTable Order by rownr OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY 
0

Nach der Forschung und nach den Kommentaren, Die klare und zusammenfassende Antwort lautet: "Es gibt keinen Weg!"

Aber Sie können Ihre Sortierreihenfolge mit row_number() bleiben. So Ich habe eine neue getestete Abfrage zur Verfügung gestellt, die die Sortierreihenfolge der temporären Tabelle (Finaltabelle) mit OFFSET und FETCH-Klausel bleiben.

INSERT INTO @TempTable [some columns] 
    select [some columns],row_number() OVER (order by col1) row from table1 order by col1 

    declare @maxrow int 
    select @maxrow=max(rn) from @TempTable 

    INSERT INTO @TempTable [same columns] 
    select [some columns],((row_number() OVER (order by col2)) + @maxrow) row from table2 order by col2 

    select * from @TempTable Order by row OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY 
10

Sie nicht mit OFFSET die erforderliche Syntax eines ORDER BY verwenden und FETCH vermeiden können.

Es ist jedoch möglich, die ORDER BY-Klausel zu trennen, die Sie angeben müssen, um Auslagerungen aus der natürlichen Tabellenreihenfolge auszuführen, die durch den Datensatzeinfügeprozess erstellt wurde.

unter Ihnen die Lösung Verwenden Sie keine Änderungen an der zugrunde liegenden Tabelle vornehmen müssen entweder

Select 0 as TempSort, T.* From MyTable T ORDER BY TempSort OFFSET 2 ROWS FETCH NEXT 3 ROWS 
+0

Das ist eine großartige, reine und sofortige SQL SELECT-Korrektur, ohne temporäre Tabellen, Identitätsspalten oder andere SQL Server-Besonderheiten. Für all jene Leute, die sich mit RDBMS-Anbietern streiten, haben Sie Recht, uns die Verwendung von ORDER BY aufzuzwingen: Sie liegen falsch! Einfaches sofortiges Paging soll einen Frame zwischen Offset n und Offset m des Datensatzes erhalten, egal wie es von einer Plattform bestellt wird. Beachten Sie, dass diese Datensätze immer noch Zeilen in der gleichen Reihenfolge für einen bestimmten Lieferanten zurückgeben, selbst wenn ORDER BY überhaupt nicht angegeben wurde! Es ist nicht immer richtig, uns zu zwingen, ORDER BY zu verwenden. –

6

Es gibt eine noch einfachere Möglichkeit, eine Dummy-ORDER BY-Klausel der Bereitstellung:

select * from @TempTable ORDER BY(SELECT NULL) OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY 
+1

Ich liebe es. Ausgezeichnete Lösung für ein dummes Problem. – user52875

0

Offset/Fetch benötigt eine order by-Klausel. Sie können das CURRENT_TIMESTAMP verwenden, um diese Anforderung zu umgehen, wenn Sie keine Bestellung ausführen möchten. Ich bin nicht sicher, aber soll diese Zeilen zurück basierend auf der Reihenfolge der Speicherung (Clustered-Index vielleicht)

So Ihren Code zu diesem Wechsel soll das Problem lösen -

INSERT INTO @TempTable [some columns] 
select [some columns] from table1 order by col1 
INSERT INTO @TempTable [same columns] 
select [some columns] from table2 order by col2 
select * from @TempTable **order by current_timestamp** OFFSET 20 ROWS FETCH NEXT 50 ROWS ONLY 
Verwandte Themen