Lekérdezések írása közben lehetőségünk van arra, hogy egyes műveleteket adat window-okban (ablakokban) hajtsunk végre.
Egy window megadásához egy összesítő vagy window függvény meghívása után az OVER()
kulcsszót használjuk.
window_function()
OVER ([order_clause])
A particionálás alatt azt a folyamatot értjük, amely során nagy adattáblákat több, kisebb részre darabolunk.
Az adatok több részre bontása növelheti a teljesítményt, mivel a lekérdezéseknek csak kisebb adathalmazokon kell lefutniuk.
A particionálás célja a nagy adattáblák karbantartásának segítése és az adatok lekérdezéséhez szükséges idő csökkentése.
Partíciók segítségével a rekordokat csoportokba sorolhatjuk. Ehhez a PARTITION BY
kulcsszavakat kell használnunk.
window_function()
OVER (PARTITION BY expr [order_clause] [frame_clause])
OVER()
kifejezésben használjuk (ezzel definiáljuk a window-t).ROW_NUMBER()
).OVER()
kifejezésből a PARTITION BY
kulcsszavakat, akkor az egész tábla egy partícióként lesz kezelve.Példa:
hacker
nevű tábla:h_id | h_name | challenge_id | score |
---|---|---|---|
3 | shubh | 111 | 20 |
2 | aayush | 111 | 80 |
5 | krithik | 112 | 40 |
5 | krithik | 114 | 90 |
4 | tushar | 112 | 30 |
1 | parth | 112 | 40 |
Meg kell találnunk a helyezését a hackereknek minden kihívásban. Tehát ki kell listáznunk minden résztvevőt a kihívásokban a helyezésükkel együtt, amit az adott kihívásban elértek.
A lekérdezés:
SELECT challenge_id, h_id, h_name, score,
dense_rank() OVER (PARTITION BY challenge_id ORDER BY score DESC)
AS rank, FROM hacker;
PARTITION BY
kifejezés particionálja a táblát csoportokba, amelyek rendelkeznek valamilyen challenge_id
értékkel.ORDER BY
kulcsszavak sorba rendezik a hackereket minden egyes partíción belül az elért pontszámok (score
) alapján.OVER()
kifejezés definiálja az ablakot, tehát, hogy hogyan kell particionálni és rendezni a rekordokat a táblában, amiket aztán partíciónként feldolgoz a rank()
window függvény.dense_rank()
egy olyan window függvény, amely sorszámot rendel minden rendezett partíciójához a kihívásoknak. Ha két hacker ugyanazzal a pontszámmal rendelkezik, akkor ugyanazt a sorszámot (helyezést) kapják.Az output:
challenge_id | h_id | h_name | score | rank |
---|---|---|---|---|
111 | 2 | aayush | 80 | 1 |
111 | 3 | shubh | 20 | 2 |
112 | 5 | krithik | 40 | 1 |
112 | 1 | parth | 40 | 1 |
112 | 4 | tushar | 30 | 2 |
114 | 5 | krithik | 90 | 1 |
A Window függvények összesítő és sorszámozó műveleteket hajtanak végre rekordok egy adott csoportján (ablakán), amelyek valahogy kapcsolódnak az éppen aktuális rekordhoz.
OVER()
kifejezéssel adjuk meg.Az összesítő függvényekkel szemben a window függvények nem csoportosítják egy output rekordba az összes rekordot, hanem minden rekord megőrzi a saját “egyéniségét”.
A szokásos összesítő függvények (pl.: SUM()
, COUNT()
, AVG()
, MAX()
, MIN()
) is használhatók rekordok egy ablakára. Ilyenkor összesítő window függvényeknek nevezzük őket.
Fontos, hogy nem használhatunk hagyományosan összesítő függvényeket és összesítő window függvényeket egy lekérdezésben. Más szavakkal, ha GROUP BY
-t használunk, akkor window függvényeket nem használhatunk.
Példa 1: Számoljuk ki a teljes másodpercben mért időtartamot running_total
néven az egész adathalmazt véve, start_time
szerint rendezve.
SELECT duration_seconds,
SUM(duration_seconds) OVER (ORDER BY start_time) AS running_total
FROM tutorial.dc_bikeshare_q1_2012;
SELECT start_terminal, duration_seconds,
SUM(duration_seconds) OVER (PARTITION BY start_terminal ORDER BY start_time) AS running_total
FROM tutorial.dc_bikeshare_q1_2012
WHERE start_time < '2012-01-08';
start_terminal
mező alapján. A mező minden értékénél start_time
szerint rendezve kiszámításra kerül a teljes időtartam.Példa 2: Szeretnénk részlegenként kiszámítani az alkalmazottak átlagos fizetését.
name | age | department | salary |
---|---|---|---|
Ramesh | 20 | Finance | 50, 000 |
Deep | 25 | Sales | 30, 000 |
Suresh | 22 | Finance | 50000 |
Ram | 28 | Finance | 20, 000 |
Pradeep | 22 | Sales | 20, 000 |
SELECT name, age, department, salary,
AVG(salary) OVER(PARTITION BY department) AS avg_salary,
FROM employee;
name | age | department | salary | avg_salary |
---|---|---|---|---|
Ramesh | 20 | Finance | 50,000 | 40,000 |
Suresh | 22 | Finance | 50000 | 40,000 |
Ram | 28 | Finance | 20,000 | 40,000 |
Pradeep | 22 | Sales | 20,000 | 25,000 |
Deep | 25 | Sales | 30,000 | 25,000 |
SELECT name, age, department, salary,
AVG(salary) OVER(PARTITION BY department ORDER BY age) AS avg_salary
FROM employee;
name | age | department | salary | avg_salary |
---|---|---|---|---|
Ramesh | 20 | Finance | 50, 000 | 50, 000 |
Suresh | 22 | Finance | 50000 | 50, 000 |
Ram | 28 | Finance | 20, 000 | 40, 000 |
Pradeep | 22 | Sales | 20, 000 | 20, 000 |
Deep | 25 | Sales | 30, 000 | 25, 000 |
Sorszámozó window függvények:
RANK()
: Minden partícióban számozza a rekordokat. Az első sor 1-es sorszámot kap, majd minden azonos tartalmú rekord azonos számot fog kapni. Azonos számozás után a következő rekord egy (vagy több, az azonos számok darabszámától függően) szám kihagyásával kapja a következő számot.
DENSE_RANK()
: Hasonlóan működik, mint a RANK()
függvény, csak ha azonos tartalmú rekordokat talál, akkor a következő különböző rekordnál nem hagy ki számokat.
ROW_NUMBER()
: Szekvenciális sorszámot rendel minden új rekordhoz egy partíción belül. Két azonos érték esetén a partíción belül két különböző sorszámot fog a rekordokhoz rendelni.
A sorszámozó window függvények használatakor a partíciók rendezése kötelező az ORDER BY
kulcsszavakkal.
Példa:
SELECT
ROW_NUMBER() OVER (PARTITION BY department ORDER BY salary DESC)
AS emp_row_no, name, department, salary,
RANK() OVER(PARTITION BY department
ORDER BY salary DESC) AS emp_rank,
DENSE_RANK() OVER(PARTITION BY department
ORDER BY salary DESC)
AS emp_dense_rank,
FROM employee;
emp_row_no | name | department | salary | emp_rank | emp_dense_rank |
---|---|---|---|---|---|
1 | Suresh | Finance | 50, 000 | 1 | 1 |
2 | Ramesh | Finance | 50, 000 | 1 | 1 |
3 | Ram | Finance | 20, 000 | 3 | 2 |
1 | Deep | Sales | 30, 000 | 1 | 1 |
2 | Pradeep | Sales | 20, 000 | 2 | 2 |
További window függvények:
Window aliasok definiálása: