GSBD Oracle SQL
GSBD Oracle SQL
--1
select min(salary), max(salary), max(salary)-min(salary) As Deiferenta,
e.department_id, d.department_name
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
order by 3 desc
;
--2
select min(salary), max(salary), max(salary)-min(salary) As Deiferenta, j.job_id,
j.job_title
from employees e inner join jobs j on e.job_id = j.job_id
group by j.job_id, j.job_title
order by 3 desc
;
--2B
select min(salary), max(salary), max(salary)-min(salary) As Deiferenta, j.job_title,
d.department_name
from employees e inner join jobs j on e.job_id = j.job_id
inner join departments d on e.department_id = d.department_id
group by j.job_title, d.department_name
order by 3 desc
;
--3.
SELECT
COUNT(e.employee_id)
FROM
employees e
INNER JOIN jobs j ON e.job_id = j.job_id
WHERE
j.job_title LIKE '%Manager%';
--4.
select d.department_name, count(e.employee_id)
from employees e inner join departments d on e.department_id = d.department_id
group by d.department_name
having count(e.employee_id) <= 5
order by 2 desc;
--5.
select d.department_name, round(avg(salary),2)
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
order by 2 desc;
select * from (
select d.department_name, round(avg(salary),2), rank() over(order by avg(salary)
desc) AS PozitieClasament
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
)
where PozitieClasament <= 3;
--6
select l.city, round(avg(salary),2)
from employees e inner join departments d on e.department_id = d.department_id
inner join locations l on d.location_id = l.location_id
group by l.city;
--7
select l.city, round(avg(salary),2)
from employees e inner join departments d on e.department_id = d.department_id
inner join locations l on d.location_id = l.location_id
group by l.city
having avg(salary)>=3500
order by 2 desc;
--8
select d.department_name, round(avg(salary),2), count(employee_id)
from employees e inner join departments d on e.department_id = d.department_id
group by e.department_id, d.department_name
having count(employee_id) >= 5
order by 2 desc;
--9
select sef.employee_id, sef.first_name || ' ' || sef.last_name,
count(ang.employee_id) nrAngajati, round(avg(ang.salary),2) salMediu
from employees ang inner join employees sef on ang.manager_id = sef.employee_id
group by sef.employee_id,sef.first_name || ' ' || sef.last_name
order by salMediu desc
;
--verificare
select avg(salary) from employees where manager_id=100;
Group by - 2 + diverse ranking
--persoanele care au fost angajate inaintea sefului lor
select ang.last_name, ang.hire_date, sef.last_name, sef.hire_date
from employees ang inner join employees sef
on ang.manager_id = sef.employee_id
where ang.hire_date < sef.hire_date;
--lunile si anii in care s-au angajat mai mult de 5 persoane in organizatia mea
select to_char(hire_date, 'MON-YYYY') LunaSiAn, count(*) NrAngInLunaAn
from employees
group by to_char(hire_date, 'MON-YYYY')
having count(*) > 5;
--care sint departamentle care au cel putin 5 angcare au comision din vinzari
select department_id, count(*) nr_ang, count(commission_pct) nr_ang_cu_comision
from employees
group by department_id
having count(commission_pct)>=5;
----select salary, count(salary) from employees group by salary order by salary desc
-- avem nevoie de sub-interogare corelata cu parintele
--
Detalii
http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.1+Analytic+SQL+Overview/
http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.2+Ranking+Functions/
http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.3+Windowing+Functions/
http://etutorials.org/SQL/Mastering+Oracle+SQL/Chapter+14.+Advanced+Analytic+SQ
L/14.4+Reporting+Functions/
https://blogs.oracle.com/oraclemagazine/a-window-into-the-world-of-analytic-functions
http://www.java2s.com/Tutorial/Oracle/0320__Analytical-
Functions/Catalog0320__Analytical-Functions.htm
http://www.vertabelo.com/blog/technical-articles/oracle-sql-analytical-functions-for-
beginners-a-gentle-introduction-to-common-sql-window-functions
https://www.blendo.co/blog/sql-window-functions/
-- angajatii care cistiga cell mai mare salariu pentru fiecare tip de functie
select * from (
select last_name, salary, job_id,department_id,
rank() over(partition by job_id order by salary desc) j_rnk
from employees
order by job_id
)
where j_rnk = 1;
--angajat care cistiga un salariu mai mare ca media pentru departamentul lor
select * from (
select last_name, salary, department_id
, round(avg(salary) over (partition by department_id)) medie_sal_dep
, round(median(salary) over (partition by department_id)) mediana_sal_dep
from employees
) where salary > medie_sal_dep;
select * from (
select AnAngajare
, max(NrCrtPersAngPeAn) maxim
, row_number() over(order by max(NrCrtPersAngPeAn) desc) nrCrt
from (
select last_name, hire_date, to_char(hire_date, 'yyyy') AnAngajare
,row_number() over(partition by to_char(hire_date, 'yyyy') order by
to_char(hire_date, 'yyyy')) NrCrtPersAngPeAn
from employees
)
group by AnAngajare
order by 2
) where nrcrt=1;
select * from (
select AnAngajare,NrCrtPersAngPeAn,
row_number() over(order by NrCrtPersAngPeAn desc) nrcrt
from (
select distinct to_char(hire_date, 'yyyy') AnAngajare
,count(*) over(partition by to_char(hire_date, 'yyyy') order by
to_char(hire_date, 'yyyy')) NrCrtPersAngPeAn
from employees
)
) where nrcrt=1;
--exista mai multe departamente cu acelasi sef? / o persoana conduce mai multe
departament?
select * from departments where manager_id in (
select manager_id from (
select department_id, department_name, manager_id, ---am nevoie doar de
manager_id + NrCrt_managerid
row_number() over(partition by manager_id order by manager_id)
NrCrt_managerid
from departments
order by manager_id
) where nrcrt_managerid >= 2 and manager_id is not null ---o persoana
conduce mai multe departament?
)
;
Subinterogari
--interogai in alte interogari
------------
select * from employees where salary in (select salary from employees where
last_name='Cambrault');
------
select * from employees where (salary, department_id) in (
select min(salary), department_id from employees group by department_id
);
select * from employees where salary = (
select min(salary) from employees group by department_id
);
---
select department_id, avg(salary) from employees
group by department_id
having avg(salary) >= (select avg(salary) from employees where
department_id=30);
select * from employees e where exists (select 1 from employees ang where
ang.manager_id = e.employee_id);
---ang.care cistiga cel mai mare sal pentru fievare tip de functie
select * from employees
where salary in (select max(salary) from employees group by job_id);
--ang care cistiga mai mult decit media dep. din care fac parte
select * from employees e where salary > (select avg(salary) from employees e2 where
e.department_id = e2.department_id group by department_id);
select * from employees e where not exists (select employee_id from job_history jh
where jh.employee_id = e.employee_id);
--sa afisam detlii despre job-uri pentru pers. care anteriro au fost angajate pe
poztie de IT_PROG
select * from jobs where job_id in (
select job_id from employees where employee_id in (
select employee_id from job_history where job_id='IT_PROG'
)
);
--toate inf.depsre angajatii care cistiga intre cel mai mic salariu din depart.lor
si 3000
select * from employees e where salary > (
select min(salary) from employees e2 where e.department_id = e2.department_id group
by department_id
) and salary < 3000;
--pers.al caror salariu este mai mic decit ale oricaror pers.cu job_id=FI_MGR
select * from employees e
where salary < (select salary from employees where job_id='FI_MGR');
--pt fiecare angajar o comparatie cu sal.mediu din depart lui si sal.mediu din org,
inclusiv diferentele si starea (mai mare/mai mic, egal)
select employee_id, salary, salary-sal_med_org, salary-sal_med_depart, sal_med_org,
sal_med_depart
,case when salary > sal_med_org then '+ med.sal.org' else '- med.sal.org' end as
Stare_med_sal_org
,case when salary > sal_med_depart then '+ med.sal.depart' else '- decit
med.sal.depart' end as Stare_med_sal_depart
from (
select employee_id, salary,
(select round(avg(salary)) from employees) sal_med_org,
(select round(avg(salary)) from employees e2 where e2.department_id =
e.department_id) sal_med_depart
from employees e
);
with x as (
select employee_id, salary,
(select round(avg(salary)) from employees) sal_med_org,
(select round(avg(salary)) from employees e2 where e2.department_id =
e.department_id) sal_med_depart
from employees e
)
select employee_id, salary, salary-sal_med_org, salary-sal_med_depart, sal_med_org,
sal_med_depart
,case when salary > sal_med_org then '+ med.sal.org' else '- med.sal.org' end as
Stare_med_sal_org
,case when salary > sal_med_depart then '+ med.sal.depart' else '- decit
med.sal.depart' end as Stare_med_sal_depart
from x;
Subinterogari – exercitii
--care sint angajatii cu job-ul "Stock Manager"
Select * from employees where job_id=(SELECT job_id from jobs where job_title='Stock
Manager');
--numele si data angajarii pentru pers. care au fost angajate dupa persoana cu id-ul
101
select first_name, last_name, hire_date from employees
where hire_date > (select hire_date from employees where employee_id = 101)
order by hire_date;
--depart. pentru care costul total mediu al salariului este mai mare decit costul
mediu pe organizatie
select AVG(salary) as salariu_total_mediu, department_id
from employees
group by department_id
having avg(salary) > ( select AVG(salary) from employees );
--cu CTE
with
nr_pe_depart as (
select department_id, count(*) nr_ang, sum(salary) sum_sal
from employees
group by department_id
),
nr_total as (
select count(*) totalAng, sum(salary) totalSal from employees
)
select nr_pe_depart.department_id, round(nr_pe_depart.nr_ang / nr_total.totalang *
100, 2), round(nr_pe_depart.sum_sal / nr_total.totalsal * 100, 2)
from nr_pe_depart, nr_total;
--
select nr_pe_depart.department_id, (select department_name from departments where
nr_pe_depart.department_id=department_id) as nume_departament,
round(nr_pe_depart.nr_ang / nr_total.totalang * 100, 2),
round(nr_pe_depart.sum_sal / nr_total.totalsal * 100, 2)
from
(select department_id, count(*) nr_ang, sum(salary) sum_sal from employees group
by department_id) nr_pe_depart
,
(select count(*) totalAng, sum(salary) totalSal from employees) nr_total;
DML – MERGE
http://psoug.org/reference/merge.html
https://www.oracletutorial.com/oracle-basics/oracle-merge/
https://livesql.oracle.com/apex/livesql/file/content_PC76LRDFFAVI6P6LMCWJLBOP2.
html
declare
v_empid emp2.employee_id%type := 1;
v_sal number(10,2);
v_nume varchar(100);
v_jobid emp2.job_id%type;
begin
loop
begin
select first_name || ' ' || last_name, salary, job_id into v_nume, v_sal,
v_jobid from employees where employee_id = v_empid;
exception
when others then
dbms_output.put_line('nu exista date pt id=' || v_empid || ' ...
cod=' ||sqlcode);
end;
v_empid := v_empid+1;
commit;
end;
PLSQL - de mutat toti angajatii de pe postul SH_CLERK --->
ST_CLERK in tabela Angajat, cu pastrare istoric, inclusiv salariu in
Ang_job_hist. La "end_date" se completeaza data curenta
declare
v_empid angajat.employee_id%type;
v_start_date angajat.hire_date%type;
v_end_date ang_job_hist.end_date%type;
v_job_id angajat.job_id%type;
v_department_id angajat.department_id%type;
v_salariu angajat.salary%type;
v_salariu_nou ang_job_hist.salariu%type;
v_empid_max angajat.employee_id%type;
begin
Cursoare – 1
declare
v_end_date date;
v_salariu_nou ang_job_hist.salariu%type;
cursor c1 is
select * from angajat where upper(job_id) = 'ST_CLERK';
vrc c1%rowtype;
begin
dbms_output.put_line('inceput prelucrare...');
begin
dbms_output.put_line('prelucrare id=' || vrc.employee_id);
end if;
exception
when others then
dbms_output.put_line('eroare angajat v_empid' || sqlcode);
end;
exit when c1%notfound; ---iesire din cursor cind nu mai exita date de
prelucrat
end loop;
close c1;
exception
when others then
dbms_output.put_line('eroare' || sqlcode);
end;
Cursor 2 - cu parametri
declare
v_end_date date;
v_salariu_nou ang_job_hist.salariu%type;
v_job_destinatie angajat.job_id%type;
vrc c1%rowtype;
begin
dbms_output.put_line('inceput prelucrare...');
v_job_destinatie := 'ST_CLERK';
if c1%isopen = false THEN
open c1 ('SH_CLERK', '18-11-2020') ; --deschide cursor daca nu este
deschis
end if;
begin
dbms_output.put_line('prelucrare id=' || vrc.employee_id);
exception
when others then
dbms_output.put_line('eroare angajat v_empid ' || vrc.employee_id || '
cod=' || sqlcode);
end;
exit when c1%notfound; ---iesire din cursor cind nu mai exita date de
prelucrat
end loop;
close c1;
exception
when others then
dbms_output.put_line('eroare' || sqlcode);
end;
Cursoare 4 – FOR
set SERVEROUTPUT On;
declare
v_crestere angajat.salary%type;
v_salariu_nou angajat.salary%type;
v_buget angajat.salary%type:=0;
--in buget voi aduna
begin
dbms_output.put_line('inceput prelucrare...');
exception
when others then
dbms_output.put_line('eroare angajat v_empid ' || vrc.employee_id || '
cod=' || sqlcode);
end;
exception
when others then
dbms_output.put_line('eroare' || sqlcode);
end;
declare
vrc cAngajati%rowtype;
cursor cDepartamente is
select * from departments;
vrd cDepartamente%rowtype;
begin
dbms_output.put_line('inceput prelucrare...');
begin
dbms_output.put_line('prelucrare department_id=' || vrd.department_id);
begin
dbms_output.put_line(vrc.employee_id);
exception
when NO_DATA_FOUND then
dbms_output.put_line('employee_id=' || vrc.employee_id || '
nu are un departament alocat');
end;
end loop;
end;
end loop;
end;
return v_rez;
end;
idx number;
numarInregistrare number:=0;
begin
idx:= 1;
v_rez.extend;
idx := v_rez.last; --ultima inregistrare
v_rez(idx).numeAng := rec.NUME;
v_rez(idx).numeDepart := rec.department_name;
v_rez(idx).salariu := rec.salary;
v_rez(idx).numefunctie := rec.job_id;
end if;
end loop;
return v_rez;
end;