sql valodas vaicājums select - datubaze.files.wordpress.com€¦ · web viewsql valodas vaicājums...
TRANSCRIPT
Hierarhiskas datu struktūrasHierarhiskas attiecības starp darbiniekiem un vadītājiem
create table DARBINIEKI(D_NUM number Primary Key,D_UZV varchar2(10),VAD_NUM number);
begininsert into DARBINIEKI values(1, 'Sakne', NULL );insert into DARBINIEKI values (2, 'Zars', 1);insert into DARBINIEKI values (3, 'Celms', 2);insert into DARBINIEKI values (4, 'Lapa', 2);insert into DARBINIEKI values (5, 'Koks', 4);insert into DARBINIEKI values (6, 'Liepa', 4);insert into DARBINIEKI values (7, 'Ozols', 1);insert into DARBINIEKI values (8, 'Egle', 7);insert into DARBINIEKI values (9, 'Priede', 1);insert into DARBINIEKI values (10, 'Apse', 9);insert into DARBINIEKI values (11, 'Goba', 10);insert into DARBINIEKI values (12, 'Bumbiere', 9);insert into DARBINIEKI values (13, 'Atvase', NULL);insert into DARBINIEKI values (14, 'Roze', 13);insert into DARBINIEKI values (15, 'Cinis', 14);insert into DARBINIEKI values (16, 'Zirnis', 14);end;
1 Sakne 13 Atvase
2 Zars 7 Ozols 9 Priede 14 Roze
3 Celms 4 Lapa 8 EgleAtvase
10 Apse 12 Bumbiere
6 Liepa5 Koks 16 Zirnis 15 Cinis11 Goba
1
Saknes mezglu atrašanaSELECT A.D_NUM, A.D_UZVFROM Darbinieki AWHERE A.VAD_NUM IS NULL;
D_NUM D_UZV--------------------------- 1 Sakne 13 Atvase
Vecāku mezglu atrašanaSELECT A.D_UZV Darbinieks, B.D_UZV VaditajsFROM Darbinieki A, Darbinieki BWHERE A.VAD_NUM = B.D_NUM;
DARBINIEKS VADITAJS----------------------------------------Priede SakneOzols SakneZars SakneLapa ZarsCelms Zars . . . Roze AtvaseZirnis RozeCinis Roze
Lapu mezglu atrašanaSELECT A.D_UZV Mezgli_lapasFROM Darbinieki AWHERE NOT EXISTS (SELECT D_NUM FROM Darbinieki B WHERE B.VAD_NUM = A.D_NUM);
MEZGLI_LAPAS--------------------------KoksEgle. . . Liepa
2
Hierarhiskas struktūras elementi1. Mezgla punkts, mezgls (node).
2. Vecāka mezgla punkts (parent node).
3. Bērna mezgla punkts (child node).
4. Sakne (root).
5. Lapa (leaf).
6. Līmenis (level).
3
Speciāla konstrukcija hierarhisko vaicājumu veidošanai
Lai vieglāk veidotu vaicājumus, kas saistīti ar hierarhiskām datu struktūrām, SQL
ir iekļautas speciālas struktūras un funkcijas:
1) START WITH – norāda apskatāmās hierarhijas sakni (-es);
2) CONNECT BY - nosaka saites starp vecāku un bērnu rakstiem;
3) PRIOR – aiz PRIOR uzreiz seko vecāku mezgla norāde (var būt vairāki);
4) LEVEL – hierarhijas līmeņa norāde.
Noteikumā “condition” var iekļaut apakšvaicājumu.
...PRIOR izteiksme = izteiksme (var izmantot ne tikai =)vai ...izteiksme = PRIOR izteiksme
CONNECT_BY_ROOT – izvada saknes elementuCONNECT_BY_ISLEAF – 1, ja ir lapa, 0, ja nav lapaCONNECT_BY_ISCYCLE – 1, ja ir bērna element, 0, ja nav bērna lementaSYS_CONNECT_BY_PATH – izvada hierarhijuOrder SIBLING by – kārtība pēc vienu vecāku bērniem
4
SQL hierarhisko paplašinājumu izmantošana
SELECT A.VAD_NUM Vad_numurs, A.D_UZV Darb_uzvards, A.D_NUM Darb_numurs FROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
VAD_NUMURS DARB_UZVARDS DARB_NUMURS------------------------------------------------------------------------------------------- -- Atvase 13 13 Priede 9 13 Roze 14 9 Apse 10 9 Bumbiere 12 14 Cinis 15 14 Zirnis 16
5
SELECT A.VAD_NUM Vad_numurs, A.D_UZV Darb_uzvards, A.D_NUM Darb_numurs FROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY PRIOR A.VAD_NUM = A.D_NUM;
VAD_NUMURS DARB_UZVARDS DARB_NUMURS---------------------------------------------------------------------------------- Atvase 13
SELECT A.D_UZV, LEVEL, SYS_CONNECT_BY_PATH(A.D_UZV, '/') HierarhijaFROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
D_UZV LEVEL HIERARHIJA Atvase 1 /Atvase Priede 2 /Atvase/Priede Apse 3 /Atvase/Priede/Apse Goba 4 /Atvase/Priede/Apse/Goba Bumbiere 3 /Atvase/Priede/Bumbiere Roze 2 /Atvase/Roze Cinis 3 /Atvase/Roze/Cinis Zirnis 3 /Atvase/Roze/Zirnis
6
Lapu noteikšana
SELECT A.D_UZV, connect_by_isleafFROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
Noteikšana vai ir cikls
SELECT A.D_UZV, connect_by_cycleFROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY NOCYCLE PRIOR A.D_NUM = A.VAD_NUM;
Noteikšana vai ir cikls
SELECT A.D_UZV, LEVEL-1, connect_by_root A.VAD_NUMFROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
11 Goba
7
SELECT VAD_NUM Vad_numurs, A.D_UZV Darb_uzvards, A.D_NUM Darb_numursFROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY A.D_NUM = A.VAD_NUM;
VAD_NUMURS DARB_UZVARDS DARB_NUMURS-------------------------------------------------------------------------------------------- -- Atvase 13
SELECT VAD_NUM Vad_numurs, A.D_UZV Darb_uzvards, A.D_NUM Darb_numursFROM Darbinieki ASTART WITH A.D_NUM = 13 CONNECT BY A.VAD_NUM = A.D_NUM;
VAD_NUMURS DARB_UZVARDS DARB_NUMURS------------------------------------------------------------------------------------------- Atvase 13
8
SELECT A.D_NUM, A.D_UZV, A.VAD_NUM, LEVELFROM Darbinieki ASTART WITH A.D_NUM = 1 CONNECT BY PRIOR A.D_NUM = A.VAD_NUMORDER BY LEVEL;
D_NUM D_UZV VAD_NUM LEVEL---------------------------------------------------------------- 1 Sakne 1 2 Zars 1 2 7 Ozols 1 2 9 Priede 1 2 3 Celms 2 3 10 Apse 9 3 12 Bumbiere 9 3 8 Egle 7 3 4 Lapa 2 3 5 Koks 4 4 11 Goba 10 4 6 Liepa 4 4
9
SELECT A.D_NUM, A.D_UZV, A.VAD_NUM, LEVELFROM Darbinieki AWHERE LEVEL = 2START WITH A.D_NUM = 1 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
D_NUM D_UZV VAD_NUM LEVEL------------------------------------------------------------------ 2 Zars 1 2 7 Ozols 1 2 9 Priede 1 2
SELECT COUNT(DISTINCT LEVEL) FROM Darbinieki A START WITH A.D_NUM = 1 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM; COUNT(DISTINCTLEVEL)---------------------------------------- 4
SELECT LEVEL, COUNT(A.D_NUM) FROM Darbinieki A START WITH A.D_NUM = 1 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM GROUP BY LEVEL; LEVEL COUNT(A.D_NUM)--------------------------------------- 1 1 2 3 3 5 4 3
10
SELECT LEVEL, LPAD(‘ ‘, 2*(LEVEL -1)) || D_UZV Darbinieki, A.D_NUM, A.VAD_NUM FROM Darbinieki A START WITH A.D_NUM = 1 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
LEVEL DARBINIEKI D_NUM VAD_NUM--------------------------------------------------------------------------- 1 Sakne 1 2 Zars 2 1 3 Celms 3 2 3 Lapa 4 2 4 Koks 5 4 4 Liepa 6 4 2 Ozols 7 1 3 Egle 8 7 2 Priede 9 1 3 Apse 10 9 4 Goba 11 10 3 Bumbiere 12 9
SELECT A.D_NUM, A.D_UZV, A.VAD_NUM FROM Darbinieki A START WITH A.D_NUM = (SELECT B.D_NUM FROM Darbinieki B WHERE B.D_UZV = ‘Lapa’) CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
D_NUM D_UZV VAD_NUM------------------------------------------------- 4 Lapa 2 5 Koks 4 6 Liepa 4
11
SELECT A.D_NUM, A.D_UZV, A.VAD_NUM FROM Darbinieki A WHERE A.D_UZV = ‘Lapa’ START WITH A.D_NUM = 2 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
D_NUM D_UZV VAD_NUM------------------------------------------------------ 4 Lapa 2
SELECT SUM(A.D_NUM) FROM Darbinieki A START WITH A.D_NUM = 2 CONNECT BY PRIOR A.D_NUM = A.VAD_NUM;
SUM(A.D_NUM)-------------------------- 20 (2 + 3 + 4+ 5 + 6)
SELECT A.D_NUM, A.D_UZV, A.VAD_NUM FROM Darbinieki A WHERE LEVEL = 1 START WITH A.VAD_NUM IS NULL CONNECT BY A.VAD_NUM = PRIOR A.D_NUM;
D_NUM D_UZV VAD_NUM------------------------------------------------------- 1 Sakne 13 Atvase
12
create table DARBINIEKI(DA_NUM number Primary key,DA_UZV varchar2(20),ALGA number(8,2),DE_NUM number,VADIT_NU number);
insert into DARBINIEKI values(1, 'Sakne', 900,1,NULL);insert into DARBINIEKI values(2, 'Zars', 800,1,1);insert into DARBINIEKI values(3, 'Stumrs', 800,1,1);insert into DARBINIEKI values(4, 'Sakne', 600,1,2);insert into DARBINIEKI values(5, 'Lapa', 600,1,2);insert into DARBINIEKI values(6, 'Ozols', 800,2,1);insert into DARBINIEKI values(7, 'Osis', 700,2,6);insert into DARBINIEKI values(8, 'Alksnis', 700,2,6);insert into DARBINIEKI values(9, 'Egle', 700,2,8);insert into DARBINIEKI values(10, 'Priede', 800,3,1);insert into DARBINIEKI values(11, 'Virsis', 700,3,10);insert into DARBINIEKI values(12, 'Persiks', 600,3,11);
create table DEPARTAMENTI(DE_NUM number Primary key,DE_NOS varchar2(20));
insert into DEPARTAMENTI values(1, 'DEP1');insert into DEPARTAMENTI values(2, 'DEP2');insert into DEPARTAMENTI values(3, 'DEP3');
13
Darbinieku pakārtotības koks
1 DEP_1
2 DEP_1 3 DEP_1
4 DEP_1 5 DEP_1
6 DEP_2 10 DEP_3
9 DEP_2
8 DEP_27 DEP_2
12 DEP_3
11 DEP_3
14
Departamentu darbinieku algu summa un vidējā visu departamentu darbinieku algu summa
select 'AVG ', 0 DE_KOPĀ, AVG(c.DE_KOPĀ)from (select b.DE_NOS, SUM(a.ALGA) DE_KOPĀ from DARBINIEKI a, DEPARTAMENTI b where a.DE_NUM = b.DE_NUM group by b.DE_NOS) cUNION ALLselect e.DE_NOS, SUM(d.ALGA) DE_KOPĀ, 0 from DARBINIEKI d, DEPARTAMENTI e where d.DE_NUM = e.DE_NUM group by e.DE_NOS;
15
Pakārtotais vaicājums ar starpniecību (subquery factoring statement)
WITH DE_IZMAKSAS as ( select DE_NOS, SUM(ALGA) DE_KOPĀ from DARBINIEKI a, DEPARTAMENTI b where a.DE_NUM = b.DE_NUM group by DE_NOS), VID_IZMAKSAS as ( select SUM(DE_KOPĀ)/COUNT(*) VID from DE_IZMAKSAS)
select * from DE_IZMAKSASwhere DE_KOPĀ>= (select VID from VID_IZMAKSAS) order by DE_NOS;
Departamenta nosaukums un darbinieku algu summa.
Vidējā departamentu darbinieku algu summa.
Departamenti, kuru darbinieku algu summa ir lielāka vai vienāda ar vidējo departamentu darbinieku algu summu
16
Rekursīvs vaicājums ar starpniecību(recursive subquery factoring )
Noteikt darbiniekus, kuri tieši vai netieši sniedz pārskatus 1 darbiniekam un viņu atskaišu līmeni.The following statement shows the employees who directly or indirectly report to employee 1 and their reporting level.
WITH ATSK_1 (NUM, UZV, VADIT, ATS_LIM) AS (select DA_NUM, DA_UZV, VADIT_NU, 0 ATS_LIM from DARBINIEKI where DA_NUM = 1 UNION ALL select e.DA_NUM, e.DA_UZV, e.VADIT_NU, ATS_LIM+1 from ATSK_1 r, DARBINIEKI e where r.NUM = e.VADIT_NU )
select NUM, UZV, VADIT, ATS_LIMfrom ATSK_1order by ATS_LIM, NUM;
D_NUM=101NUM=101 VAD_ID=100 0r.NUM=101 e.VAD_ID=108 1r.NUM=101 e.VAD_ID=200 1r.NUM=101 e.VAD_ID=203 1r.NUM=101 e.VAD_ID=204 1r.NUM=101 e.VAD_ID=205 1
r.NUM=108 e.VAD_ID=109 2r.NUM=108 e.VAD_ID=110 2r.NUM=108 e.VAD_ID=111 2r.NUM=205 e.VAD_ID=206 2
17
The following statement shows employees who directly or indirectly report to employee 1, their reporting level, and their management chain.
with ATSK_1 (NUM, UZV, VADIT, ATS_LIM, VAD_SAR) AS (select DA_NUM, DA_UZV, VADIT_NU, 0 ATS_LIM, CAST(VADIT_NU as varchar2(200)) from DARBINIEKI where DA_NUM= 1 UNION ALL select e.DA_NUM, e.DA_UZV, e.VADIT_NU, ATS_LIM+1, CAST(VAD_SAR || ',' || VADIT_NU as varchar2(200)) FROM ATSK_1 r, DARBINIEKI e WHERE r.NUM = e.VADIT_NU )
select NUM, UZV, VADIT, ATS_LIM, VAD_SARfrom ATSK_1order by ATS_LIM, NUM;
18
The following statement shows the employees who directly or indirectly report to employee 1 and their reporting level. It stops at reporting level 1.
with ATSK_1 (NUM, UZV, VADIT, ATS_LIM, VAD_SAR) AS (select DA_NUM, DA_UZV, VADIT_NU, 0 ATS_LIM, CAST(VADIT_NU as varchar2(200)) from DARBINIEKI where DA_NUM= 1 UNION ALL select e.DA_NUM, e.DA_UZV, e.VADIT_NU, ATS_LIM+1, CAST(VAD_SAR || ',' || VADIT_NU as varchar2(200)) FROM ATSK_1 r, DARBINIEKI e WHERE r.NUM = e.VADIT_NU )select NUM, UZV, VADIT, ATS_LIM, VAD_SARfrom ATSK_1where ATS_LIM <=1order by ATS_LIM, NUM;
19
The following statement shows the entire organization, indenting for each level of management.
with POZ_IZV (NUM, UZV, VADIT, ATS_LIM, ALGA) as (select DA_NUM, DA_UZV, VADIT_NU, 0 ATS_LIM, ALGA from DARBINIEKI where VADIT_NU is null UNION ALL SELECT e.DA_NUM, e.DA_UZV, e.VADIT_NU, r.ATS_LIM+1 ATS_LIM, e.ALGA from POZ_IZV r, DARBINIEKI e WHERE r.NUM = e.VADIT_NU) SEARCH DEPTH FIRST BY UZV SET order1select LPAD(' ',2*ATS_LIM)||UZV uzvārds, NUM, VADIT, ALGAfrom POZ_IZVorder by order1;
20
The following statement shows the entire organization, indenting for each level of management, with each level ordered by hire_date. The value of is_cycle is set to Y for any employee who has the same hire_date as any manager above him in the management chain.
WITH dup_hiredate (eid, emp_last, mgr_id, reportLevel, hire_date, job_id) AS ( SELECT employee_id, last_name, manager_id, 0 reportLevel, hire_date, job_id FROM employees WHERE manager_id is null UNION ALL SELECT e.employee_id, e.last_name, e.manager_id, r.reportLevel+1 reportLevel, e.hire_date, e.job_id FROM dup_hiredate r, employees e WHERE r.eid = e.manager_id ) SEARCH DEPTH FIRST BY hire_date SET order1 CYCLE hire_date SET is_cycle TO 'Y' DEFAULT 'N'SELECT lpad(' ',2*reportLevel)||emp_last emp_name, eid, mgr_id, hire_date, job_id, is_cycleFROM dup_hiredateORDER BY order1;
EMP_NAME EID MGR_ID HIRE_DATE JOB_ID IS_CYCLE-------------------- ---------- ---------- --------- ---------- --------King 100 17-JUN-03 AD_PRES N De Haan 102 100 13-JAN-01 AD_VP N Hunold 103 102 03-JAN-06 IT_PROG N Austin 105 103 25-JUN-05 IT_PROG N. . . Kochhar 101 100 21-SEP-05 AD_VP N Mavris 203 101 07-JUN-02 HR_REP N Baer 204 101 07-JUN-02 PR_REP N
21
Higgins 205 101 07-JUN-02 AC_MGR N Gietz 206 205 07-JUN-02 AC_ACCOUNT Y Greenberg 108 101 17-AUG-02 FI_MGR N Faviet 109 108 16-AUG-02 FI_ACCOUNT N Chen 110 108 28-SEP-05 FI_ACCOUNT N. . .
The following statement counts the number of employees under each manager.
22
The following statement counts the number of employees under each manager.
WITH emp_count (eid, emp_last, mgr_id, mgrLevel, salary, cnt_employees) AS ( SELECT employee_id, last_name, manager_id, 0 mgrLevel, salary, 0 cnt_employees FROM employees UNION ALL SELECT e.employee_id, e.last_name, e.manager_id, r.mgrLevel+1 mgrLevel, e.salary, 1 cnt_employees FROM emp_count r, employees e WHERE e.employee_id = r.mgr_id ) SEARCH DEPTH FIRST BY emp_last SET order1SELECT emp_last, eid, mgr_id, salary, sum(cnt_employees), max(mgrLevel) mgrLevelFROM emp_countGROUP BY emp_last, eid, mgr_id, salaryHAVING max(mgrLevel) > 0ORDER BY mgr_id NULLS FIRST, emp_last;
EMP_LAST EID MGR_ID SALARY SUM(CNT_EMPLOYEES) MGRLEVEL------------------ ---------- ---------- ---------- ------------------ ----------King 100 24000 106 3Cambrault 148 100 11000 7 2De Haan 102 100 17000 5 2Errazuriz 147 100 12000 6 1Fripp 121 100 8200 8 1Hartstein 201 100 13000 1 1Kaufling 122 100 7900 8 1. . .
23