Czy istnieje sposób, aby Oracle
zapytanie zachowywało się tak, jakby zawierało MySQL limit
klauzulę?
W MySQL
mogę 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 rownum
pseudo-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.
sql
oracle
pagination
sql-limit
Mathieu Longtin
źródło
źródło
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.Odpowiedzi:
Począwszy od Oracle 12c R1 (12,1), nie jest rząd ograniczenie zapis . Nie korzysta ze znanej
LIMIT
skł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:
(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ć
Co jest w tabeli
Zdobądź pierwsze
N
rzędyUzyskaj pierwsze
N
wiersze, jeśliN
th wiersz ma więzi, uzyskać wszystkie związane wierszeGórny
x
% wierszyUżywanie przesunięcia, bardzo przydatne do stronicowania
Możesz połączyć przesunięcie z wartościami procentowymi
źródło
OFFSET FETCH
składnia to cukier składniowy. SzczegółyW tym celu można użyć podzapytania
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
(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ęć.
Zobacz tę odpowiedź, aby uzyskać więcej przykładów. Dzięki Krumii za podpowiedź.
źródło
Przeprowadziłem testy wydajności dla następujących podejść:
Asktom
Analityczny
Krótka alternatywa
Wyniki
Tabela miała 10 milionów rekordów, sortowanie było w nieindeksowanym wierszu daty i godziny:
Wybór pierwszych 10 wierszy zajął:
Wybieranie wierszy od 100 000 do 100 010:
Wybieranie wierszy od 9 000 000 do 9 000 010:
źródło
BETWEEN
to tylko skrót>= AND <=
( stackoverflow.com/questions/4809083/between-clause-versus-and )offset
składnia ma taki sam plan i wydajność jak podejście analityczne.Rozwiązanie analityczne z tylko jednym zagnieżdżonym zapytaniem:
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.źródło
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 gdyrank()
może. W każdym razierow_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.W Oracle 12c (patrz klauzula ograniczająca wiersze w dokumentacji SQL ):
źródło
LIMIT
SQL: 2008, musieli następnie wyciągnąć liść z książki Microsoftu i złamać standard.LIMIT ... OFFSET
LIMIT n, m
(Zobacz moją odpowiedź). Z drugiej strony Oracle powinien był zaimplementowaćLIMIT n, m
jako cukier składniowy, ponieważ jest to równoważneOFFSET n ROWS FETCH NEXT m ROWS ONLY
.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:
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:
Dowiedz się więcej o zapytaniach dotyczących paginacji w moich artykułach na blogu Vertabelo :
źródło
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:
Oracle 11g i starsze wersje
Przed wersją 12c, aby pobrać rekordy Top-N, trzeba było użyć tabeli pochodnej i pseudokolumny ROWNUM:
źródło
Mniej instrukcji SELECT. Ponadto mniej energochłonne. Kredyty dla: [email protected]
źródło
Jako rozszerzenie przyjętej odpowiedzi Oracle wewnętrznie korzysta z
ROW_NUMBER/RANK
funkcji.OFFSET FETCH
składnia to cukier składniowy.Można to zaobserwować, stosując
DBMS_UTILITY.EXPAND_SQL_TEXT
procedurę:Przygotowanie próbki:
Pytanie:
jest regularny:
db <> demo skrzypiec
Pobieranie rozszerzonego tekstu SQL:
WITH TIES
jest rozwinięty jakoRANK
:i przesunięcie:
źródło
Jeśli nie korzystasz z Oracle 12C, możesz użyć zapytania TOP N, jak poniżej.
Możesz nawet przenieść to z klauzuli z klauzulą w następujący sposób
Tutaj tworzymy widok wbudowany i zmieniamy nazwę rownum na rnum. Możesz użyć rnum w głównym zapytaniu jako kryterium filtru.
źródło
ORDER BY
irownum
oddzielnie. Zasadniczo utworzyłem pod-zapytanie, które miałoORDER BY
klauzulę .rownum
powinno znajdować się poza podkwerendą.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
Przykład:
źródło
większe niż wartości dowiedzieć się
dowiedz się mniej niż wartości
źródło
ROW_NUMBER()
oparte na downvote zostało już opublikowane przez Leigh Riffela. Uzależnione są błędy składniowe w pokazanym kodzie.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.
Zaimplementowałem to na
oracle
serwerze11.2.0.1.0
źródło
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!
źródło
W wyroczni
VAL
Wybrano 5 wierszy.
SQL>
źródło
(niesprawdzone) coś takiego może wykonać zadanie
Istnieje również ranga funkcji analitycznej, według której można sortować według.
źródło
To samo co powyżej z poprawkami. Działa, ale zdecydowanie nie jest ładna.
Szczerze mówiąc, lepiej skorzystać z powyższych odpowiedzi.
źródło