2015-06-22 11 views
7

Chcę użyć PRZESUNIĘCIE i Pobierz w moim kwerendy SQL Server 2012.Ale bez żadnego zamówienia przez.I nie można użyć kolejności przez. Ponieważ moje sortowanie zostaną utracone. Jak korzystać z funkcji PRZESUNIĘCIE i pobierania bez zamówienia według numeru wiersza i miejsca w zapytaniu? Moje 2 wybrane tabele mają tę samą strukturę.Jak używać PRZESUNIĘCIE i Pobierz bez porządku przez 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 

To zapytanie ma błąd składniowy przy słowie kluczowym OFFSET.

+3

'offsetu FETCH' jest stosowana tylko na * zamówionych * zestawach. W tabeli SQL nie ma żadnej nieodłącznej kolejności i * masz * używać 'ORDER BY', jeśli chcesz ją określić. Dlatego to, czego chcesz, po prostu nie jest możliwe. –

+0

Czy mogę użyć zamówienia przez 1? –

+2

Tak, oczywiście, chociaż nie rozumiem, co masz na myśli przez *, ponieważ mój porządek sortowania zostanie utracony *. W tabeli nie ma nieodłącznego porządku sortowania, który mógłby zostać utracony. –

Odpowiedz

6

Dodając kolumnę identyczności z tabeli temp zmiennej

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 

automatyczny przyrost liczby dodano w każdym wierszu w kolejności w której są one dodawane do tabeli temp. Wkładki nie muszą wypełniać tej kolumny, więc wkładki mogą pozostać takie, jakie są. Kolumna tożsamości mogą być następnie wykorzystane do porządku przez:

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

Po badaniach i zgodnie z uwagami, przejrzysta i pełna odpowiedź brzmi: "Nie ma mowy!"

Możesz jednak zachować kolejność sortowania za pomocą row_number(). Tak więc podałem nowe testowane zapytanie, które pozostaje porządkiem sortowania tabeli temp (tabela końcowa) z klauzulami OFFSET i FETCH.

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

nie można uniknąć stosując wymaganą składnię ORDER BY z OFFSET i FETCH.

Możliwe jest jednak odłączenie klauzuli ORDER BY, którą należy podać w celu wykonania stronicowania z naturalnej kolejności tabel utworzonej przez proces wstawiania rekordów.

Stosując rozwiązanie poniżej nie trzeba wprowadzać żadnych zmian w tabeli bazowej albo

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

To jest doskonała, czysta i natychmiastowa poprawka SQL SELECT, bez tabel tymczasowych, kolumn tożsamości i innych specyfikacji SQL Server. Dla wszystkich tych, którzy twierdzą, że dostawcy RDBMS mają rację, zmuszają nas do użycia ORDER BY: jesteś w błędzie! Proste natychmiastowe stronicowanie ma uzyskać ramkę między offsetem n a offsetem zbioru danych, bez względu na to, jak jest uporządkowany przez platformę. Pamiętaj, że te zestawy danych wciąż zwracają wiersze w tej samej kolejności dla określonego dostawcy, nawet jeśli ORDER BY nie zostało w ogóle określone! Zmuszanie nas do używania ORDER BY nie zawsze ma rację. –

6

Jest jeszcze prostszy sposób na zapewnienie obojętne ORDER BY:

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

Uwielbiam to. Doskonałe rozwiązanie na głupi problem. – user52875

0

offsetowy/Fetch wymaga klauzuli order by. Możesz użyć CURRENT_TIMESTAMP, aby ominąć ten wymóg, jeśli nie chcesz wykonywać żadnego zamówienia. Nie jestem pewien, ale powinno to zwrócić wiersze na podstawie kolejności magazynowej (skupione indeksu może)

Więc zmienia swój kod to powinno rozwiązać problem -

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 
Powiązane problemy