Топ-N заявки и пагинация са често срещани в уеб-базираните приложения. Потребителят въвежда набор от критерии, които изпълняват заявка и след това позволяват на потребителя да щракне върху бутоните Предишен и Следващ, за да прегледа набора от резултати. За да постигне тази функционалност за пейджинг, приложението трябва да може да получи определен набор от редове от заявката за база данни.
Нека да разгледаме различния метод в Oracle за постигане на Top-N заявки в Oracle и Страниране в Oracle заявка
Преди 12c
(1) Използване на клауза ROWNUM
Какво е ROWNUM
Това е псевдоколона (не реална колона), която е налична в заявка. ROWNUM ще бъдат присвоени числата 1, 2, 3, 4, … N , където N е броят на редовете в набора, с който се използва ROWNUM. Стойност ROWNUM не е присвоена за постоянно на ред.
Ето как да получите първите 5 стойности
SELECT * FROM (SELECT * FROM dept ORDER BY sales DESC) WHERE ROWNUM <= 5;
Тази версия ще сортира Dept по низходящи продажби и след това ще върне първите пет записа, които среща (първите пет записа).
За пагинация в oracle , ако искате 5-10 записа на Dept по описа на продажбите, тогава направете това.
SELECT a.* FROM (SELECT ROWNUM rn, b.* FROM ( SELECT * FROM dept ORDER BY sales dsc) b where rn <=10) a WHERE a.rn >= 5
Общият синтаксис би бил
select * from ( select rownum rnum, a.* from (your_query) a where rownum <= M ) where rnum >= N;
(2) Използване на аналитична функция ROW_NUMBER() на оракул:Държи се подобно на псевдо колоната ROWNUM, но е по-гъвкава и има повече възможности
Ето как да получите първите 5 стойности
SELECT * FROM (SELECT d.*,row_number() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Ето заявката за Страниране
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;
Горните Топ N заявки ще дадат връщане на различни записи, когато две неща са свързани за мястото при използване на първите n заявки
(3) Използване на RANK() и DENSE_RANK():Това са аналитична функция, която може да се използва за премахване на проблема, посочен по-горе
Ето начин за получаване на първите 5 стойности с помощта на ранг
SELECT * FROM (SELECT d.*,rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
Ето как да получите първите 5 стойности с помощта на dense_rank
SELECT * FROM (SELECT d.*,dense_rank() over (ORDER BY d.sales DSC) rn FROM dept d ) WHERE rn <= 5;
С 12c
Топ-N функция :
Oracle Database 12c включва поддръжка за ANSI-стандартните клаузи FETCH FIRST/NEXT и OFFSET – заедно наречени клауза за ограничаване на реда. Тази клауза ви позволява лесно да извлечете първите N записи от набор от резултати или, алтернативно, първите N записи след прескачане на набор от записи, така че можете лесно да прелиствате през набор от резултати
Топ-N заявка ни позволява да извлечем горните или долните N реда от подреден набор. Комбинирането на две Top-N заявки ви дава възможност да преглеждате подреден набор
Пример:
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;
Ако погледнете плана на оптимизатора за горната заявка, той все още използва row_number() под обвивката, за да го направи
Пагинацията може да се случи и с тази функция със синтаксис за използване на изместване
– отместване на 10 реда извлича само първите 10 реда
select * from my_test order by id offset 10 rows fetch next 10 rows only;
– отместване на 10 реда извлича само първите 0,1% редове
select * from my_test order by id offset 10 rows first 0.1 percent rows only;
– отместване на 10 реда извлича първите 3 реда с връзки. Това означава, че всички горни редове с връзки също ще бъдат включени в резултата
select * from my_test order by name fetch first 3 rows with ties;
Ако проверите плана на оптимизатора на горната заявка, ще откриете, че оптимизаторът използва функция rank(), както е показано по-горе в случай Pre 12c
Ограничение
(1)Ако имате израз SELECT с FOR UPDATE, не можете да го използвате.
(2)Изразът SELECT не може да CURRVAL или NEXTVAL от последователности
(3) Ако заявката на материализираните изгледи има тази клауза, тогава не можете да правите постепенно опресняване на този материализиран изглед
Надяваме се да ви хареса статията за Top-N заявки в oracle и Pagination в oracle query. Моля, дайте обратна връзка
Също чете
Водеща функция в Oracle
функция RANK в Oracle
https://docs.oracle.com/javadb/10.8.3.0/ref/rrefsqljoffsetfetch.html