Top-N dotazy a stránkování jsou běžné ve webových aplikacích. Uživatel zadá sadu kritérií, která spustí dotaz a poté umožní uživateli kliknout na tlačítka Předchozí a Další, aby mohl listovat sadou výsledků. K dosažení této funkce stránkování musí být aplikace schopna získat určitou sadu řádků z databázového dotazu.
Pojďme se podívat na různé metody v Oracle k dosažení Top-N dotazů v Oracle a stránkování v dotazu Oracle
Před 12:00
(1) Použití klauzule ROWNUM
Co je ROWNUM
Je to pseudosloupec (nikoli skutečný sloupec), který je dostupný v dotazu. ROWNUM budou mít přiřazena čísla 1, 2, 3, 4, … N , kde N je počet řádků v množině, se kterou se ROWNUM používá. Hodnota ROWNUM není k řádku trvale přiřazena.
Zde je způsob, jak získat prvních 5 hodnot
SELECT * FROM (SELECT * FROM dept ORDER BY sales DESC) WHERE ROWNUM <= 5;
Tato verze seřadí oddělení podle prodeje sestupně a poté vrátí prvních pět záznamů, na které narazí (prvních pět záznamů).
Pro stránkování v oracle, pokud chcete 5 -10 záznamů objednávky oddělení podle popisu prodeje, pak jdi do toho.
SELECT a.* FROM (SELECT ROWNUM rn, b.* FROM ( SELECT * FROM dept ORDER BY sales dsc) b where rn <=10) a WHERE a.rn >= 5
Obecná syntaxe by byla
select * from ( select rownum rnum, a.* from (your_query) a where rownum <= M ) where rnum >= N;
(2) Použití analytické funkce ROW_NUMBER() oracle:Chová se podobně jako pseudosloupec ROWNUM, ale je flexibilnější a má více možností
Zde je způsob, jak získat prvních 5 hodnot
SELECT * FROM (SELECT d.*,row_number() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Zde je dotaz pro stránkování
SELECT * FROM ( SELECT d.*, row_number() over (ORDER BY d.sales DSC) rn FROM dept d) WHERE rn BETWEEN 0 AND 5 ORDER BY rn;
Výše uvedených top N dotazů vrátí různé záznamy, když se na místě při použití top n dotazů budou shodovat dvě věci
(3) Použití RANK() a DENSE_RANK():Toto jsou analytické funkce, které lze použít k odstranění výše uvedeného problému
Zde je způsob, jak získat 5 nejlepších hodnot pomocí hodnocení
SELECT * FROM (SELECT d.*,rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Zde je způsob, jak získat prvních 5 hodnot pomocí dense_rank
SELECT * FROM (SELECT d.*,dense_rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
S 12c
Funkce Top-N :
Oracle Database 12c zahrnuje podporu pro klauzule ANSI FETCH FIRST/NEXT a OFFSET – společně nazývané klauzule omezující řádky. Tato klauzule vám umožňuje snadno načíst prvních N záznamů ze sady výsledků nebo alternativně prvních N záznamů po přeskočení sady záznamů, takže můžete snadno stránkovat sadu výsledků
Dotaz Top-N nám umožňuje získat horních nebo dolních N řádků z uspořádané sady. Kombinace dvou Top-N dotazů vám dává možnost listovat v uspořádané sadě
Příklad:
SELECT value FROM mytable ORDER BY value DESC FETCH FIRST 10 ROWS ONLY; select * from my_test order by name fetch first 3 rows only;
Pokud se podíváte na plán optimalizátoru pro výše uvedený dotaz, stále k tomu používá row_number()
Stránkování může také probíhat pomocí této funkce pomocí syntaxe use offset
– odsazení 10 řádků načte pouze prvních 10 řádků
select * from my_test order by id offset 10 rows fetch next 10 rows only;
– odsazení 10 řádků načte pouze prvních 0,1 procenta řádků
select * from my_test order by id offset 10 rows first 0.1 percent rows only;
– odsazení 10 řádků načte první 3 řádky s vazbami. Znamená to, že do výsledku budou zahrnuty také všechny horní řádky s remízou
select * from my_test order by name fetch first 3 rows with ties;
Pokud zkontrolujete plán optimalizátoru výše uvedeného dotazu, zjistíte, že optimalizátor používá funkci rank(), jak je ukázáno výše v případě Pre 12c
Omezení
(1)Pokud máte příkaz SELECT s FOR UPDATE, nemůžete jej použít.
(2)Příkaz SELECT nemůže CURRVAL nebo NEXTVAL sekvencí
(3) Pokud dotaz na materializované pohledy obsahuje tuto klauzuli, pak nemůžete provést přírůstkovou aktualizaci tohoto materializovaného pohledu
Doufám, že se vám článek o Top-N dotazech v oracle a stránkování v oracle dotazu líbí. Poskytněte nám prosím zpětnou vazbu
Také čte
Vedoucí funkce v Oracle
Funkce RANK v Oracle
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html