nie, analyticke funkcie su o tom, ze sa vykonavaju nad finalnym vysledkom
Takze najprv sa vykona subquery factoring (with), joiny, where klauzula, group by, having
az potom analyticke funkcie. Az ked mame vysledok, mozeme vykonavat nejake operacie nad tym vysledkom..
a potom sa to da este zotriedit cez order by a obmedzit limitom..
Nevím, zda je to ten samý případ, co v Oraclu, ale tam zabralo vyhodit podmínku až za select, i.e.:
select * from (select row_number() as xx from yyy) yyyi where xx = 10
Důvody viz výše, rownum určuje pořadí ve výsledku, tedy cokoliv kromě row_number() <= xxx je nesmysl. Alias z něj ve vnějším selectu udělá pevnou hodnotu. V Oraclu například vhodné pro implementaci limit :)
Upřesním - limit cnt a limit start, cnt. Pokud chcu prvních deset řádků, stačí samozřejmě jen přidat rownum <= 10. Pokud chcu limit z obou stran, je třeba to udělat složitěji, neboť podmínka z druhé strany z výše uvedených důvodů nefunguje, tedy je třeba rownum "exportovat" ven:
select ... from (select rownum as limit_row, ... from tab where filter order by sorter) where limit_row between limit_start and limit_start+limit_cnt-1
Navíc i v prvním případě, pokud bych chtěl použít order by, tak rownum nejspíš nebude fungovat podle očekávání.
najprv sa zaznamy ocisluju az potom sa zoradia.. poriadie zaznamov z toho selektu bude nahodne..
dalsia vec je ze pokial date rownum von takymto sposobom, tak nevie pouzit stop count optimalizaciu, tj zotriedi, cely vstup (aj tak zbytocne, pretoze si vyberiete zaznamy podla nezotriedeneho rownum)
nizsie som uviedol priklad ako to ma vyzerat, v tom priklade sa netriedi cely vystup ale iba prvych :higest zaznamov.
with temp_table as (select trunc(dbms_random.value(1,100)) b from dual connect by level < 5)
select temp_table.b, rownum from temp_table
order by temp_table.b
v DB2 sice funguje
WHERE rownum between X AND Y
ale neumi stop count optimalizaci. Navic optimalizer ma selectivitu tehle konstrukce uplne mimo misu (hardcoded 1/3 na 1 rownum podminku (between jsou 2)).
rownum je iba v Oracle, a inkrementuje sa s rastucim resultsetom (ked je splnena podmienka pre nejaky zaznam), takze v tom pripade naozaj vsetko ine ako rownum <= x je nezmyslel (este rownum = 1 ma zmysel)
row_number() je analyticka funkcia tak v Oracle a v Postgre, a tam je jedno ake predikaty na nu aplikujeme (v nadselekte).. - inac tato funkcia nie je v oracli lepsia z hladiska vykonu pre implementaciu pagingu ako rownum, pretoze sa vykona nad celym resultsetom, kym rownum umoznuje zastavit ziskavenie riadkov po nejakom pocte (STOPCOUNT optimalizacia),.
Priklad pagingu v oracle (ano, vyzera to hnusne :))
SELECT ename, sal, deptno FROM (
SELECT ename, sal, deptno, ROWNUM rnum FROM (
SELECT e.ename, e.sal, e.deptno
FROM emp e WHERE e.sal BETWEEN 1000 AND 3000
ORDER BY e.ename)
WHERE ROWNUM < :highest) -- stop count optimalizacia, cim neskorsia stranka tym viac prace
WHERE rnum > :lowest