Jak ograniczyć liczbę wierszy zwracanych przez zapytanie Oracle po złożeniu zamówienia?

1032

Czy istnieje sposób, aby Oraclezapytanie zachowywało się tak, jakby zawierało MySQL limitklauzulę?

W MySQLmogę to zrobić:

select * 
from sometable
order by name
limit 20,10

aby dostać 21 do 30 rzędów (pomiń pierwsze 20, podaj kolejne 10). Wiersze są wybierane po order by, więc tak naprawdę zaczyna się od 20. nazwy alfabetycznie.

W Oracle, jedyną rzeczą, ludzie wspomnieć, jest rownumpseudo-kolumny, ale to jest oceniane przed order by , która oznacza:

select * 
from sometable
where rownum <= 10
order by name

zwróci losowy zestaw dziesięciu wierszy uporządkowanych według nazwy, co zwykle nie jest tym, czego chcę. Nie pozwala również na określenie przesunięcia.

Mathieu Longtin
źródło
16
Standaryzowany w SQL: 2008.
dalle
14
Limit został ogłoszony przez Toma Kyte'a dla Oracle 12c ...
wol 3i
14
Pobierasz następną stronę w zestawie wyników?
Mathieu Longtin,
3
@YaroslavShabalin W szczególności wyszukiwanie stronicowane korzysta z tego wzorca przez cały czas. Będzie korzystać z niej prawie każda aplikacja z dowolną funkcją wyszukiwania. Innym przypadkiem użycia byłoby załadowanie tylko części długiej listy lub strony klienta tabeli i umożliwienie użytkownikowi rozwinięcia.
jpmc26
3
@YaroslavShabalin Nie można uzyskać innego zestawu wyników, chyba że dane podstawowe ulegną zmianie z powodu ORDER BY. Na tym właśnie polega sens zamawiania. Jeśli podstawowe dane ulegają zmianie, a zestaw wyników zmienia się z tego powodu, to dlaczego nie pokazać użytkownikowi zaktualizowanych wyników zamiast nieaktualnych informacji? Ponadto zarządzanie państwem jest plagą, której należy w jak największym stopniu unikać. Jest stałym źródłem komplikacji i błędów; dlatego funkcjonalność staje się tak popularna. A kiedy miałbyś wiedzieć, że wygasa cały zestaw wyników w pamięci? W sieci nie możesz wiedzieć, kiedy użytkownik odejdzie.
jpmc26

Odpowiedzi:

619

Począwszy od Oracle 12c R1 (12,1), nie jest rząd ograniczenie zapis . Nie korzysta ze znanej LIMITskładni, ale może wykonać to zadanie lepiej dzięki większej liczbie opcji. Możesz znaleźć pełną składnię tutaj . (Przeczytaj także więcej o tym, jak to działa wewnętrznie w Oracle w tej odpowiedzi ).

Aby odpowiedzieć na oryginalne pytanie, oto zapytanie:

SELECT * 
FROM   sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

(W przypadku wcześniejszych wersji Oracle zapoznaj się z innymi odpowiedziami na to pytanie)


Przykłady:

Poniższe przykłady zostały przytoczone z połączonej strony , w nadziei, że zapobiegną gniciu linków.

Ustawiać

CREATE TABLE rownum_order_test (
  val  NUMBER
);

INSERT ALL
  INTO rownum_order_test
SELECT level
FROM   dual
CONNECT BY level <= 10;

COMMIT;

Co jest w tabeli

SELECT val
FROM   rownum_order_test
ORDER BY val;

       VAL
----------
         1
         1
         2
         2
         3
         3
         4
         4
         5
         5
         6
         6
         7
         7
         8
         8
         9
         9
        10
        10

20 rows selected.

Zdobądź pierwsze Nrzędy

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;

       VAL
----------
        10
        10
         9
         9
         8

5 rows selected.

Uzyskaj pierwsze Nwiersze, jeśli Nth wiersz ma więzi, uzyskać wszystkie związane wiersze

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS WITH TIES;

       VAL
----------
        10
        10
         9
         9
         8
         8

6 rows selected.

Górny x% wierszy

SELECT val
FROM   rownum_order_test
ORDER BY val
FETCH FIRST 20 PERCENT ROWS ONLY;

       VAL
----------
         1
         1
         2
         2

4 rows selected.

Używanie przesunięcia, bardzo przydatne do stronicowania

SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY;

       VAL
----------
         3
         3
         4
         4

4 rows selected.

Możesz połączyć przesunięcie z wartościami procentowymi

SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 20 PERCENT ROWS ONLY;

       VAL
----------
         3
         3
         4
         4

4 rows selected.
sampathsris
źródło
1
Po prostu: OFFSET FETCHskładnia to cukier składniowy. Szczegóły
Łukasz Szozda,
793

W tym celu można użyć podzapytania

select *
from  
( select * 
  from emp 
  order by sal desc ) 
where ROWNUM <= 5;

Więcej informacji można znaleźć w temacie O ROWNUM i ograniczaniu wyników w Oracle / AskTom.

Aktualizacja : Aby ograniczyć wynik zarówno z dolną, jak i górną granicą, rzeczy stają się bardziej rozdęte

select * from 
( select a.*, ROWNUM rnum from 
  ( <your_query_goes_here, with order by> ) a 
  where ROWNUM <= :MAX_ROW_TO_FETCH )
where rnum  >= :MIN_ROW_TO_FETCH;

(Skopiowano z określonego artykułu AskTom)

Aktualizacja 2 : Począwszy od Oracle 12c (12.1) dostępna jest składnia ograniczająca wiersze lub rozpoczynająca się od przesunięć.

SELECT * 
FROM   sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;

Zobacz tę odpowiedź, aby uzyskać więcej przykładów. Dzięki Krumii za podpowiedź.

Kosi2801
źródło
5
Jest to zdecydowanie sposób, aby to zrobić, ale należy pamiętać (jak mówi artykuł z pytaniem), że wydajność zapytania spada wraz ze wzrostem maksymalnej liczby miejsc. To dobre rozwiązanie dla wyników zapytań, w których chcesz zobaczyć tylko kilka pierwszych stron, ale jeśli używasz tego jako mechanizmu do stronicowania całej tabeli, lepiej byłoby zrefaktoryzować kod
Chris Gill
1
+1 twoja dolna / górna wersja faktycznie pomogła mi obejść problem, w którym zwykła górna granica klauzuli rownum drastycznie spowolniła moje zapytanie.
Kelvin,
1
Leigh Riffel „rozwiązanie analityczne z tylko jednym zagnieżdżonym zapytaniem” to jedno.
Darren Hicks
7
Artykuł AskTom zawiera również wskazówkę dotyczącą optymalizacji, która wykorzystuje SELECT / * + FIRST_ROWS (n) / a. , rownum rnum Ukośnik zamykający powinien być poprzedzony gwiazdką. SO to szoruje.
David Mann
1
Zauważ, że dla Oracle 11 zewnętrzny SELECT z ROWNUM uniemożliwi Ci wywołanie deleteRow na UpdatableResultSet (z ORA-01446) - nie mogę się doczekać tej zmiany R1c 12c!
nsandersen
185

Przeprowadziłem testy wydajności dla następujących podejść:

Asktom

select * from (
  select a.*, ROWNUM rnum from (
    <select statement with order by clause>
  ) a where rownum <= MAX_ROW
) where rnum >= MIN_ROW

Analityczny

select * from (
  <select statement with order by clause>
) where myrow between MIN_ROW and MAX_ROW

Krótka alternatywa

select * from (
  select statement, rownum as RN with order by clause
) where a.rn >= MIN_ROW and a.rn <= MAX_ROW

Wyniki

Tabela miała 10 milionów rekordów, sortowanie było w nieindeksowanym wierszu daty i godziny:

  • Wyjaśnij plan pokazał tę samą wartość dla wszystkich trzech wybranych (323168)
  • Ale zwycięzcą jest AskTom (z analizą podążającą tuż za)

Wybór pierwszych 10 wierszy zajął:

  • AskTom: 28-30 sekund
  • Analityczne: 33-37 sekund
  • Krótka alternatywa: 110-140 sekund

Wybieranie wierszy od 100 000 do 100 010:

  • AskTom: 60 sekund
  • Analityczny: 100 sekund

Wybieranie wierszy od 9 000 000 do 9 000 010:

  • AskTom: 130 sekund
  • Analityczny: 150 sekund
zeldi
źródło
Dobra robota. Czy wypróbowałeś krótką alternatywę z pomiędzy zamiast zamiast> = i <=?
Mathieu Longtin,
4
@MathieuLongtin BETWEENto tylko skrót >= AND <=( stackoverflow.com/questions/4809083/between-clause-versus-and )
wweicker,
1
zeldi - w której wersji to było? Firma Oracle wprowadziła analityczne ulepszenia wydajności w wersji 11.1. i 11.2.
Leigh Riffel,
@Leigh Riffel Było 10.2.0.5; pewnego dnia mogę poświęcić trochę czasu i sprawdzić wersję 11i.
zeldi 11.03.13
5
Przeprowadziłem kilka szybkich testów i uzyskałem podobne wyniki dla 12c. Nowa offsetskładnia ma taki sam plan i wydajność jak podejście analityczne.
Jon Heller
55

Rozwiązanie analityczne z tylko jednym zagnieżdżonym zapytaniem:

SELECT * FROM
(
   SELECT t.*, Row_Number() OVER (ORDER BY name) MyRow FROM sometable t
) 
WHERE MyRow BETWEEN 10 AND 20;

Rank()może zostać zastąpione, Row_Number()ale może zwrócić więcej rekordów niż się spodziewasz, jeśli dla nazwy istnieją zduplikowane wartości.

Leigh Riffel
źródło
3
Uwielbiam analizy. Możesz wyjaśnić, jaka byłaby różnica w zachowaniu między Rank () a Row_Number ().
Dave Costa
Rzeczywiście, nie jestem pewien, dlaczego nie myślałem o duplikatach. Zatem w tym przypadku, jeśli istnieją zduplikowane wartości dla nazwy, RANK może dać więcej rekordów, niż się spodziewasz, dlatego powinieneś użyć Row_Number.
Leigh Riffel
Jeśli wspomnę rank(), warto również zauważyć, dense_rank()które mogą być bardziej przydatne do kontroli wyjścia, ponieważ ta ostatnia nie „pomija” liczb, podczas gdy rank()może. W każdym razie row_number()najlepiej jest odpowiedzieć na to pytanie . Innym nie jest to, że ta technika ma zastosowanie do dowolnej bazy danych obsługującej wspomniane funkcje.
Used_By_Already
28

W Oracle 12c (patrz klauzula ograniczająca wiersze w dokumentacji SQL ):

SELECT * 
FROM sometable
ORDER BY name
OFFSET 20 ROWS FETCH NEXT 10 ROWS ONLY;
Beldaz
źródło
53
I oczywiście musieli użyć zupełnie innej składni niż dotychczas
Mathieu Longtin,
9
Najwyraźniej po tym, jak usiedli ze wszystkimi innymi dostawcami, aby zgodzić się na LIMITSQL: 2008, musieli następnie wyciągnąć liść z książki Microsoftu i złamać standard.
beldaz
1
Co ciekawe, ostatnio słyszałem, że najnowszy standard zawiera tę składnię, więc być może Oracle wdrożyło ją najpierw przed wdrożeniem. Prawdopodobnie jest bardziej elastyczny niżLIMIT ... OFFSET
beldaz
3
@Derek: Tak, godne pożałowania jest nieprzestrzeganie tego standardu. Ale nowo wprowadzona funkcjonalność w 12cR1 ma większą moc niż tylko LIMIT n, m(Zobacz moją odpowiedź). Z drugiej strony Oracle powinien był zaimplementować LIMIT n, mjako cukier składniowy, ponieważ jest to równoważne OFFSET n ROWS FETCH NEXT m ROWS ONLY.
sampathsris
10
@Derek: Właściwie właśnie zauważyłem tę uwagę w podręczniku PostgreSQL postgresql.org/docs/9.0/static/sql-select.html#AEN69535 „Klauzule LIMIT i OFFSET są składnią specyficzną dla PostgreSQL, również używaną przez MySQL. SQL : 2008 standard wprowadził klauzule OFFSET ... FETCH {FIRST | NEXT} ... dla tej samej funkcjonalności ". LIMIT nigdy nie był częścią standardu.
beldaz
14

Zapytania dotyczące paginacji z kolejnością są w Oracle bardzo trudne.

Oracle udostępnia pseudokolumnę ROWNUM, która zwraca liczbę wskazującą kolejność, w jakiej baza danych wybiera wiersz z tabeli lub zestawu połączonych widoków.

ROWNUM to pseudokolumna, która wpędza wielu ludzi w kłopoty. Wartość ROWNUM nie jest na stałe przypisywana do wiersza (jest to powszechne nieporozumienie). Może być mylące, gdy faktycznie przypisano wartość ROWNUM. Wartość ROWNUM jest przypisywana do wiersza po przejściu predykatów filtru zapytania, ale przed agregacją lub sortowaniem zapytania .

Co więcej, wartość ROWNUM jest zwiększana dopiero po przypisaniu.

Dlatego zapytanie następujące nie zwraca żadnych wierszy:

 select * 
 from (select *
       from some_table
       order by some_column)
 where ROWNUM <= 4 and ROWNUM > 1; 

Pierwszy wiersz wyniku zapytania nie przechodzi predykatem ROWNUM> 1, więc ROWNUM nie zwiększa się do 2. Z tego powodu żadna wartość ROWNUM nie jest większa niż 1, w związku z czym zapytanie nie zwraca wierszy.

Prawidłowo zdefiniowane zapytanie powinno wyglądać następująco:

select *
from (select *, ROWNUM rnum
      from (select *
            from skijump_results
            order by points)
      where ROWNUM <= 4)
where rnum > 1; 

Dowiedz się więcej o zapytaniach dotyczących paginacji w moich artykułach na blogu Vertabelo :

Bartek
źródło
2
Pierwszy wiersz wyniku zapytania nie przekazuje predykatu ROWNUM > 1 (…) - głosowanie za wyjaśnieniem tego.
Piotr Dobrogost
6

Standard SQL

Jak wyjaśniłem w tym artykule , SQL: 2008 Standard zapewnia następującą składnię w celu ograniczenia zestawu wyników SQL:

SELECT
    title
FROM
    post
ORDER BY
    id DESC
FETCH FIRST 50 ROWS ONLY

Oracle 11g i starsze wersje

Przed wersją 12c, aby pobrać rekordy Top-N, trzeba było użyć tabeli pochodnej i pseudokolumny ROWNUM:

SELECT *
FROM (
    SELECT
        title
    FROM
        post
    ORDER BY
        id DESC
)
WHERE ROWNUM <= 50
Vlad Mihalcea
źródło
5

Mniej instrukcji SELECT. Ponadto mniej energochłonne. Kredyty dla: [email protected]

SELECT *
    FROM   (SELECT t.*,
                   rownum AS rn
            FROM   shhospede t) a
    WHERE  a.rn >= in_first
    AND    a.rn <= in_first;
Felipe Q. Giovanoni
źródło
2
Co więcej, jest to całkowicie niepoprawna odpowiedź. Pytanie dotyczyło ograniczenia PO sortowaniu. Więc rownum powinno być poza podzapytaniem.
BitLord,
5

Jako rozszerzenie przyjętej odpowiedzi Oracle wewnętrznie korzysta z ROW_NUMBER/RANKfunkcji. OFFSET FETCHskładnia to cukier składniowy.

Można to zaobserwować, stosując DBMS_UTILITY.EXPAND_SQL_TEXTprocedurę:

Przygotowanie próbki:

CREATE TABLE rownum_order_test (
  val  NUMBER
);

INSERT ALL
  INTO rownum_order_test
SELECT level
FROM   dual
CONNECT BY level <= 10;
COMMIT;

Pytanie:

SELECT val
FROM   rownum_order_test
ORDER BY val DESC
FETCH FIRST 5 ROWS ONLY;

jest regularny:

SELECT "A1"."VAL" "VAL" 
FROM  (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
               ROW_NUMBER() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rownumber" 
      FROM "ROWNUM_ORDER_TEST" "A2") "A1" 
WHERE "A1"."rowlimit_$$_rownumber"<=5 ORDER BY "A1"."rowlimit_$_0" DESC;

db <> demo skrzypiec

Pobieranie rozszerzonego tekstu SQL:

declare
  x VARCHAR2(1000);
begin
 dbms_utility.expand_sql_text(
        input_sql_text => '
          SELECT val
          FROM   rownum_order_test
          ORDER BY val DESC
          FETCH FIRST 5 ROWS ONLY',
        output_sql_text => x);

  dbms_output.put_line(x);
end;
/

WITH TIESjest rozwinięty jako RANK:

declare
  x VARCHAR2(1000);
begin
 dbms_utility.expand_sql_text(
        input_sql_text => '
          SELECT val
          FROM   rownum_order_test
          ORDER BY val DESC
          FETCH FIRST 5 ROWS WITH TIES',
        output_sql_text => x);

  dbms_output.put_line(x);
end;
/

SELECT "A1"."VAL" "VAL" 
FROM  (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
              RANK() OVER ( ORDER BY "A2"."VAL" DESC ) "rowlimit_$$_rank" 
       FROM "ROWNUM_ORDER_TEST" "A2") "A1" 
WHERE "A1"."rowlimit_$$_rank"<=5 ORDER BY "A1"."rowlimit_$_0" DESC

i przesunięcie:

declare
  x VARCHAR2(1000);
begin
 dbms_utility.expand_sql_text(
        input_sql_text => '
          SELECT val
FROM   rownum_order_test
ORDER BY val
OFFSET 4 ROWS FETCH NEXT 4 ROWS ONLY',
        output_sql_text => x);

  dbms_output.put_line(x);
end;
/


SELECT "A1"."VAL" "VAL" 
FROM  (SELECT "A2"."VAL" "VAL","A2"."VAL" "rowlimit_$_0",
             ROW_NUMBER() OVER ( ORDER BY "A2"."VAL") "rowlimit_$$_rownumber" 
       FROM "ROWNUM_ORDER_TEST" "A2") "A1" 
       WHERE "A1"."rowlimit_$$_rownumber"<=CASE  WHEN (4>=0) THEN FLOOR(TO_NUMBER(4)) 
             ELSE 0 END +4 AND "A1"."rowlimit_$$_rownumber">4 
ORDER BY "A1"."rowlimit_$_0"
Łukasz Szozda
źródło
3

Jeśli nie korzystasz z Oracle 12C, możesz użyć zapytania TOP N, jak poniżej.

SELECT *
 FROM
   ( SELECT rownum rnum
          , a.*
       FROM sometable a 
   ORDER BY name
   )
WHERE rnum BETWEEN 10 AND 20;

Możesz nawet przenieść to z klauzuli z klauzulą ​​w następujący sposób

WITH b AS
( SELECT rownum rnum
      , a.* 
   FROM sometable a ORDER BY name
) 
SELECT * FROM b 
WHERE rnum BETWEEN 10 AND 20;

Tutaj tworzymy widok wbudowany i zmieniamy nazwę rownum na rnum. Możesz użyć rnum w głównym zapytaniu jako kryterium filtru.

sandi
źródło
1
W moim przypadku nie zwróciło to odpowiednich wierszy. Co zrobiłem, aby to naprawić to zrobić ORDER BYi rownumoddzielnie. Zasadniczo utworzyłem pod-zapytanie, które miało ORDER BYklauzulę .
Patrick Gregorio,
Głosuj negatywnie, ponieważ jest to nieprawidłowa odpowiedź. Pytanie dotyczyło ograniczenia po sortowaniu, więc rownumpowinno znajdować się poza podkwerendą.
Piotr Dobrogost
@PiotrDobrogost rownum jest tylko na zewnątrz.
sandi
2

Zacząłem przygotowywać się do egzaminu Oracle 1z0-047, sprawdzonego pod kątem 12c. Przygotowując się do niego, natknąłem się na ulepszenie 12c znane jako „FETCH FIRST”. Pozwala ono pobierać wiersze / ograniczać wiersze według własnego uznania. Dostępnych jest kilka opcji

- FETCH FIRST n ROWS ONLY
 - OFFSET n ROWS FETCH NEXT N1 ROWS ONLY // leave the n rows and display next N1 rows
 - n % rows via FETCH FIRST N PERCENT ROWS ONLY

Przykład:

Select * from XYZ a
order by a.pqr
FETCH FIRST 10 ROWS ONLY
Arjun Gaur
źródło
3
stackoverflow.com/a/26051830/635608 - zostało to już podane w innych odpowiedziach. Powstrzymaj się od publikowania materiałów, które zostały już opublikowane miesiące temu.
Mat
1
och, jasne, nie przejrzałem wszystkich odpowiedzi, wcześnie natknąłem się na podkwerendy, będę o tym pamiętać.
arjun gaur
1
select * FROM (SELECT 
   ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
 FROM EMP ) EMP  where ROWID=5

większe niż wartości dowiedzieć się

select * FROM (SELECT 
       ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
     FROM EMP ) EMP  where ROWID>5

dowiedz się mniej niż wartości

select * FROM (SELECT 
       ROW_NUMBER() OVER (ORDER BY sal desc),* AS ROWID, 
     FROM EMP ) EMP  where ROWID=5
Mehul Akabari
źródło
Rozwiązanie ROW_NUMBER()oparte na downvote zostało już opublikowane przez Leigh Riffela. Uzależnione są błędy składniowe w pokazanym kodzie.
Piotr Dobrogost
1

Dla każdego wiersza zwróconego przez zapytanie pseudokolumna ROWNUM zwraca liczbę wskazującą kolejność, w jakiej Oracle wybiera wiersz z tabeli lub zestawu połączonych wierszy. Pierwszy wybrany wiersz ma ROWNUM 1, drugi ma 2 i tak dalej.

  SELECT * FROM sometable1 so
    WHERE so.id IN (
    SELECT so2.id from sometable2 so2
    WHERE ROWNUM <=5
    )
    AND ORDER BY so.somefield AND ROWNUM <= 100 

Zaimplementowałem to na oracleserwerze11.2.0.1.0

Sumesh TG
źródło
głosuj negatywnie, ponieważ pytanie dotyczy ograniczenia liczby zamówionych wierszy, a ty nawet nie masz zamówienia
Piotr Dobrogost
@PiotrDobrogost Rozumiem, że nie jest to duże zadanie, porządkowanie słów kluczowych jest wspólne dla wszystkich rdbms, tylko limit ma zmiany.
Sumesh TG
-1

W przypadku SQL-Developer automatycznie pobiera tylko pierwsze 50 wierszy. A jeśli przewiniemy w dół, pobierze kolejne 50 wierszy i tak dalej!

Dlatego nie musimy definiować, w przypadku narzędzia SQL Developer!

Aditya Goel
źródło
-3

W wyroczni

SELECT val FROM   rownum_order_test ORDER BY val DESC FETCH FIRST 5 ROWS ONLY;

VAL

    10
    10
     9
     9
     8

Wybrano 5 wierszy.

SQL>

Rakesh
źródło
7
Powinieneś sprecyzować, że dotyczy to zaczynając od Oracle 12c i że gdzieś kopiujesz / wklejasz - zawsze cytuj swoje źródła.
Mat.
Źródłem jest ten @Mat. I Rakesh, spróbuj przynajmniej dostosować odpowiedź na pierwotne pytanie. Podałem również odpowiedź cytując to samo źródło, ale starałem się być wyczerpujący i zacytowałem oryginalne źródło.
sampathsris
-4

(niesprawdzone) coś takiego może wykonać zadanie

WITH
base AS
(
    select *                   -- get the table
    from sometable
    order by name              -- in the desired order
),
twenty AS
(
    select *                   -- get the first 30 rows
    from base
    where rownum < 30
    order by name              -- in the desired order
)
select *                       -- then get rows 21 .. 30
from twenty
where rownum > 20
order by name                  -- in the desired order

Istnieje również ranga funkcji analitycznej, według której można sortować według.

EvilTeach
źródło
2
Nie zwróci to ani jednego wiersza, ponieważ ROWNUM jest kolumną w zestawie wyników, więc ostatni warunek GDZIE zawsze będzie fałszywy. Ponadto nie możesz korzystać z ROWNUM i ZAMÓWIENIA NA ZAMÓWIENIE gwarancji.
Ben
2
Świetny. Zostawmy to tutaj jako ostrzeżenie dla innych.
EvilTeach
-5

To samo co powyżej z poprawkami. Działa, ale zdecydowanie nie jest ładna.

   WITH
    base AS
    (
        select *                   -- get the table
        from sometable
        order by name              -- in the desired order
    ),
    twenty AS
    (
        select *                   -- get the first 30 rows
        from base
        where rownum <= 30
        order by name              -- in the desired order
    )
    select *                       -- then get rows 21 .. 30
    from twenty
    where rownum < 20
    order by name                  -- in the desired order

Szczerze mówiąc, lepiej skorzystać z powyższych odpowiedzi.

pobudzanie
źródło
5
Jest to nieprawidłowe, ponieważ klauzula WHERE jest oceniana przed ORDER BY.
Ben
3
Co ciekawe skradzione z mojej złej odpowiedzi poniżej.
EvilTeach,