KENDE MÁRIA - NAGY ISTVÁN
ANALITIKUS SQL FELADATGYŰJTEMÉNY
TARTALOM 9. Foglalkozás Részletező csoportosítások ......................................................................................... 2 10. Foglalkozás Analitikus függvények ................................................................................................ 5 Melléklet A ROW_NUMBER szintaktikája ................................................................................... 10 Irodalom .......................................................................................................................... 12
2007. február 25. #12_Analitikus SQL Feladatgyűjtemény (07)
-1-
9. Foglalkozás
Részletező csoportosítások Részletesebben lásd [2]: 13. fejezet
FELADATGYŰJTEMÉNY
9.1. Feladat Részletező csoportosítással listázza részlegenként az összfizetést és a létszámot. Az összesítő sorban a részleg oszlopába a ”Teljes összeg” szöveget írja. 9.2. Feladat Részletező csoportosítással listázza főnökönként az összfizetést és a létszámot. Ahol nincs főnök, oda a ”Nincs főnök”, az összesítő sor főnök oszlopába pedig a ”Mindösszesen” szöveget írja. TOVÁBBI FELADATOK T9.3. Feladat Készítse el a fenti feladatokat a GROUPING SETS operator segítségével is. T9.4. Feladat Részletező csoportosítással listázza részlegenként, azon belül munkakörönként az átlagos, az összes, és a legnagyobb fizetéseket, valamint a létszámot. A részletező sorokba írja be a megfelelő értelmező szövegeket.
#12_Analitikus SQL Feladatgyűjtemény (07)
-2-
MEGOLDÁSGYŰJTEMÉNY
9.1. Feladat Részletező csoportosítással listázza részlegenként az összfizetést és a létszámot. Az összesítő sorban a részleg oszlopába a ”Teljes összeg” szöveget írja. Megoldás 1. lépés A részletező csoportosítás legegyszerűbb használata SELECT deptno, SUM(sal), COUNT(*) FROM emp GROUP BY ROLLUP(deptno);
Eredmény DEPTNO SUM(SAL) COUNT(*) ---------- ---------- ---------10 8750 3 20 10875 5 30 9400 6 29025 14
2. lépés A ”Teljes összeg” szöveg beírása COLUMN "Részleg" FORMAT A15 SELECT NVL(TO_CHAR(deptno),'Teljes összeg') SUM(sal) COUNT(*) FROM emp GROUP BY ROLLUP(deptno); CLEAR COLUMN
AS "Részleg", AS "ÖsszFiz", AS "Létszám"
Eredmény Részleg ÖsszFiz Létszám --------------- ---------- ---------10 8750 3 20 10875 5 30 9400 6 Teljes összeg 29025 14
9.2. Feladat Részletező csoportosítással listázza főnökönként az összfizetést és a létszámot. Ahol nincs főnök, oda a ”Nincs főnök”, az összesítő sor főnök oszlopába pedig a ”Mindösszesen” szöveget írja. 1. Megoldás (A ROLLUP operátor segítségével) COLUMN "Főnök" FORMAT A20 SELECT CASE WHEN GROUPING(mgr) = 0 mgr IS NOT NULL THEN TO_CHAR(mgr) WHEN GROUPING(mgr) = 0 mgr IS NULL THEN 'Nincs főnök' ELSE 'Mindösszesen' END AS "Főnök",
#12_Analitikus SQL Feladatgyűjtemény (07)
AND AND
-3-
SUM(sal) COUNT(*) FROM emp GROUP BY ROLLUP(mgr); CLEAR COLUMNS
AS "ÖsszFiz", AS "Létszám"
2. Megoldás (A GROUPING SETS operátor segítségével) COLUMN "Főnök" FORMAT A20 SELECT CASE WHEN GROUPING(mgr) = 0 mgr IS NOT NULL THEN TO_CHAR(mgr) WHEN GROUPING(mgr) = 0 mgr IS NULL THEN 'Nincs főnök' ELSE 'Mindösszesen' END AS "Főnök", SUM(sal) AS "ÖsszFiz", COUNT(*) AS "Létszám" FROM emp GROUP BY GROUPING SETS((mgr),()); CLEAR COLUMNS
AND AND
Eredmény (Mindkét esetben) Főnök ÖsszFiz Létszám -------------------- ---------- ---------7566 6000 2 7698 6550 5 7782 1300 1 7788 1100 1 7839 8275 3 7902 800 1 Nincs főnök 5000 1 Mindösszesen 29025 14 8 sor kijelölve.
#12_Analitikus SQL Feladatgyűjtemény (07)
-4-
10. Foglalkozás
Analitikus függvények Részletesebben lásd [2]: 13. fejezet
FELADATGYŰJTEMÉNY
10.1. Feladat Lássuk el sorszámmal a dolgozókat, ha elsődlegesen a részleg szerint, másodlagosan a nevük szerint rendezzük. 10.2. Feladat Lássuk el minden részlegben sorszámmal a névsor szerint rendezett dolgozókat. 10.3. Feladat Lássuk el kétféle sorszámmal a dolgozókat. Az első végigsorszámozza őket, ha elsődlegesen a részleg szerint, másodlagosan a nevük szerint rendezzük, a második minden részlegben a nevük szerint rendezetten sorszámozza őket. 10.4. Feladat Lássuk el olyan összetett azonosítóval a dolgozókat, melyben az első rész a részlegazonosító, a második pedig a név szerinti rendezés alapján a részlegbeli sorszám. 10.5. Feladat Lássuk el sorszámokkal a dolgozókat a következőképpen: • legyen olyan sorszám, mely elsődlegesen a részlegazonosító, másodlagosan a dolgozók neve szerinti sorrendet tükrözi (sorszám1), • legyen olyan sorszám, mely részlegenként a dolgozók fizetése szerinti sorrendet tükrözi (sorszám2), • legyen olyan sorszám, mely megadja, hogy egy dolgozó a fizetése szerint hányadik a részlegében (NormálRangsor), • legyen olyan sorszám, mely megadja, hogy egy dolgozó fizetése hányadik a részlegében előforduló fizetések között (SűrítettRangsor) 10.6. Feladat Listázzuk minden részlegben a második legkisebb fizetésű dolgozókat. TOVÁBBI FELADATOK T10.7. Feladat Listázzuk minden részlegben a legnagyobb fizetésű dolgozókat. T10.8. Feladat Határozza meg, hogy egy, a felhasználó által megadott fizetés hányadik lenne a fizetések munkakörönkénti rangsorában? (DENSE_RANK ... WITHIN GROUP ...) T10.9. Feladat Határozza meg, hogy egy, a felhasználó által megadott fizetésű új dolgozó melyik részlegben okozza a legkisebb bérfeszültséget. (A feladat megoldásához írásban értelmezze a bérfeszültség fogalmát!)
#12_Analitikus SQL Feladatgyűjtemény (07)
-5-
MEGOLDÁSGYŰJTEMÉNY
10.1. Feladat Lássuk el sorszámmal a dolgozókat, ha elsődlegesen a részleg szerint, másodlagosan a nevük szerint rendezzük. 1. Megoldás SET numwidth 5 SELECT deptno AS részleg, ename AS név, empno AS azonosító, ROWNUM AS sorszám FROM (SELECT * FROM emp ORDER BY deptno, ename) ORDER BY sorszám;
2. Megoldás SELECT deptno ename empno ROW_NUMBER() OVER (ORDER BY deptno, ename) FROM emp;
AS részleg, AS név, AS azonosító, AS sorszám
Eredmény (Mindkét esetben) RÉSZLEG ------10 10 10 20 20 20 20 20 30 30 30 30 30 30
NÉV AZONOSÍTÓ SORSZÁM ---------- --------- ------CLARK 7782 1 KING 7839 2 MILLER 7934 3 ADAMS 7876 4 FORD 7902 5 JONES 7566 6 SCOTT 7788 7 SMITH 7369 8 ALLEN 7499 9 BLAKE 7698 10 JAMES 7900 11 MARTIN 7654 12 TURNER 7844 13 WARD 7521 14
14 sor kijelölve.
10.2. Feladat Lássuk el minden részlegben sorszámmal a névsor szerint rendezett dolgozókat. Megoldás SELECT deptno ename empno ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) FROM emp;
#12_Analitikus SQL Feladatgyűjtemény (07)
AS részleg, AS név, AS azonosító, AS sorszám
-6-
Eredmény RÉSZLEG ------10 10 10 20 20 20 20 20 30 30 30 30 30 30
NÉV AZONOSÍTÓ SORSZÁM ---------- --------- ------CLARK 7782 1 KING 7839 2 MILLER 7934 3 ADAMS 7876 1 FORD 7902 2 JONES 7566 3 SCOTT 7788 4 SMITH 7369 5 ALLEN 7499 1 BLAKE 7698 2 JAMES 7900 3 MARTIN 7654 4 TURNER 7844 5 WARD 7521 6
14 sor kijelölve.
10.3. Feladat Lássuk el kétféle sorszámmal a dolgozókat. Az első végigsorszámozza őket, ha elsődlegesen a részleg szerint, másodlagosan a nevük szerint rendezzük, a második minden részlegben a nevük szerint rendezetten sorszámozza őket. Megoldás SET numwidth 5 SELECT deptno ename empno ROW_NUMBER() OVER (ORDER BY deptno) ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename) FROM emp;
AS részleg, AS név, AS azonosító, AS sorszám1, AS sorszám2
Eredmény RÉSZLEG ------10 10 10 20 20 20 20 20 30 30 30 30 30 30
NÉV AZONOSÍTÓ SORSZÁM1 SORSZÁM2 ---------- --------- -------- -------CLARK 7782 1 1 KING 7839 2 2 MILLER 7934 3 3 ADAMS 7876 4 1 FORD 7902 5 2 JONES 7566 6 3 SCOTT 7788 7 4 SMITH 7369 8 5 ALLEN 7499 9 1 BLAKE 7698 10 2 JAMES 7900 11 3 MARTIN 7654 12 4 TURNER 7844 13 5 WARD 7521 14 6
14 sor kijelölve.
10.4. Feladat Lássuk el olyan összetett azonosítóval a dolgozókat, melyben az első rész a részlegazonosító, a második pedig a név szerinti rendezés alapján a részlegbeli sorszám. Megoldás SET numwidth 5 SELECT empno ename
#12_Analitikus SQL Feladatgyűjtemény (07)
AS "RégiAzonosító", AS "Név",
-7-
TO_CHAR(deptno) || '.' || TO_CHAR(ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY ename)) AS "ÚjAzonosító" FROM emp;
Eredmény RégiAzonosító ------------7782 7839 7934 7876 7902 7566 7788 7369 7499 7698 7900 7654 7844 7521
Név ---------CLARK KING MILLER ADAMS FORD JONES SCOTT SMITH ALLEN BLAKE JAMES MARTIN TURNER WARD
ÚjAzonosító -----------10.1 10.2 10.3 20.1 20.2 20.3 20.4 20.5 30.1 30.2 30.3 30.4 30.5 30.6
14 sor kijelölve.
10.5. Feladat Lássuk el sorszámokkal a dolgozókat a következőképpen: • legyen olyan sorszám, mely elsődlegesen a részlegazonosító, másodlagosan a dolgozók neve szerinti sorrendet tükrözi (sorszám1), • legyen olyan sorszám, mely részlegenként a dolgozók fizetése szerinti sorrendet tükrözi (sorszám2), • legyen olyan sorszám, mely megadja, hogy egy dolgozó a fizetése szerint hányadik a részlegében (NormálRangsor), • legyen olyan sorszám, mely megadja, hogy egy dolgozó fizetése hányadik a részlegében előforduló fizetések között (SűrítettRangsor) Megoldás SET numwidth 5 SELECT deptno ename sal ROW_NUMBER() OVER (ORDER BY deptno) ROW_NUMBER() OVER (PARTITION BY deptno ORDER BY sal) ROWNUM, RANK() OVER (PARTITION BY deptno ORDER BY sal) DENSE_RANK() OVER (PARTITION BY deptno ORDER BY sal) FROM emp;
AS "Részleg", AS "Név", AS "Fizetés", AS "Sorszám1", AS "Sorszám2",
AS "NormálRangsor", AS "SűrítettRangsor"
Eredmény Részleg ------10 10 10 20 20
Név Fizetés Sorszám1 Sorszám2 ROWNUM NormálRangsor SűrítettRangsor ---------- ------- -------- -------- ------ ------------- --------------MILLER 1300 1 1 14 1 1 CLARK 2450 2 2 7 2 2 KING 5000 3 3 9 3 3 SMITH 800 4 1 1 1 1 ADAMS 1100 5 2 11 2 2
#12_Analitikus SQL Feladatgyűjtemény (07)
-8-
20 20 20 30 30 30 30 30 30
JONES SCOTT FORD JAMES WARD MARTIN TURNER ALLEN BLAKE
2975 3000 3000 950 1250 1250 1500 1600 2850
6 7 8 9 10 11 12 13 14
3 4 5 1 2 3 4 5 6
4 8 13 12 3 5 10 2 6
3 4 4 1 2 2 4 5 6
14 sor kijelölve.
10.6. Feladat Listázzuk minden részlegben a második legkisebb fizetésű dolgozókat. Megoldás SET numwidth 5
1. lépés Készítsünk nézetet, mely részlegenként megadja a fizetések sorrendjét: CREATE OR REPLACE VIEW FizSorrend(Részleg, Fizetés, SűrítettRangsor) AS SELECT DISTINCT deptno, sal, DENSE_RANK() OVER (PARTITION BY deptno ORDER BY sal) FROM emp; SELECT * FROM FizSorrend;
Eredmény RÉSZLEG FIZETÉS SŰRÍTETTRANGSOR ------- ------- --------------10 1300 1 10 2450 2 10 5000 3 20 800 1 20 1100 2 20 2975 3 20 3000 4 30 950 1 30 1250 2 30 1500 3 30 1600 4 30 2850 5 12 sor kijelölve.
2. lépés Listázzuk a második legkisebb jövedelműeket: SELECT emp.* FROM emp, FizSorrend WHERE emp.deptno = FizSorrend.Részleg emp.sal = FizSorrend.Fizetés SűrítettRangsor = 2;
AND AND
Eredmény EMPNO ----7782 7876 7654 7521
ENAME ---------CLARK ADAMS MARTIN WARD
JOB MGR HIREDATE SAL COMM DEPTNO --------- ----- ---------- ----- ----- -----MANAGER 7839 1981-06-09 2450 10 CLERK 7788 1987-05-23 1100 20 SALESMAN 7698 1981-09-28 1250 1400 30 SALESMAN 7698 1981-02-22 1250 500 30
#12_Analitikus SQL Feladatgyűjtemény (07)
-9-
3 4 4 1 2 2 3 4 5
Melléklet
A ROW_NUMBER szintaktikája
Oracle® Database SQL Reference 10g Release 1 (10.1) Part Number B10759-01
Home Book List Contents Index
Master Index Feedback
ROW_NUMBER Syntax row_number::=
Description of the illustration row_number.gif
See Also: "Analytic Functions " for information on syntax, semantics, and restrictions
Purpose ROW_NUMBER is an analytic function. It assigns a unique number to each row to which it is applied
(either each row in the partition or each row returned by the query), in the ordered sequence of rows specified in the order_by_clause, beginning with 1. By nesting a subquery using ROW_NUMBER inside a query that retrieves the ROW_NUMBER values for a specified range, you can find a precise subset of rows from the results of the inner query. This use of the function lets you implement top-N, bottom-N, and inner-N reporting. For consistent results, the query must ensure a deterministic sort order. You cannot use ROW_NUMBER or any other analytic function for expr. That is, you cannot nest analytic functions, but you can use other built-in function expressions for expr. Please refer to "About SQL Expressions " for information on valid forms of expr.
Examples For each department in the sample table oe.employees, the following example assigns numbers to each row in order of employee's hire date: SELECT department_id, last_name, employee_id, ROW_NUMBER() OVER (PARTITION BY department_id ORDER BY employee_id) AS emp_id FROM employees;
#12_Analitikus SQL Feladatgyűjtemény (07)
- 10 -
DEPARTMENT_ID ------------10 20 20 30 30 30 30 30 30 40 . . . 100 110 110
LAST_NAME EMPLOYEE_ID EMP_ID ------------------------- ----------- ---------Whalen 200 1 Hartstein 201 1 Fay 202 2 Raphaely 114 1 Khoo 115 2 Baida 116 3 Tobias 117 4 Himuro 118 5 Colmenares 119 6 Mavris 203 1 Popp Higgins Gietz
113 205 206
6 1 2
ROW_NUMBER is a nondeterministic function. However, employee_id is a unique key, so the
results of this application of the function are deterministic.
See Also: FIRST_VALUE and LAST_VALUE for examples of nondeterministic behavior
The following inner-N query selects all rows from the employees table but returns only the fiftyfirst through one-hundredth row: SELECT last_name FROM (SELECT last_name, ROW_NUMBER() over (order by last_name) R FROM employees) WHERE R BETWEEN 51 and 100;
Previous
Next
Copyright © 1996, 2003 Oracle Corporation All Rights Reserved. Home Book List Contents Index
#12_Analitikus SQL Feladatgyűjtemény (07)
- 11 -
Master Index Feedback
IRODALOM [1] Kende M. – Kotsis D. – Nagy I.: Adatbázis-kezelés az Oracle-rendszerben, Panem, 2002. [2] Kende M. – Nagy I.: Oracle Példatár (SQL, PL/SQL), Panem, 2005.
#12_Analitikus SQL Feladatgyűjtemény (07)
- 12 -