Wielotabelowy insert (Multitable insert)
Przypuśćmy że wynik poniższego zapytania:
select department_name, count(*), max(salary), min(salary),round(avg(salary))
from employees join departments using(department_id) group by department_name;
Chciałbym załadować do kilku tabel,
rozbijając wynik na wiele elementów. Przykładowo do tabeli
„liczba_pracowników” trafiłaby nazwa departamentu i liczba
pracowników, do tabeli „srednie_zarobki” trafiłaby nazwa tabeli
i średnie zarobki etc.
W pierwszej kolejności tworzę tabele
do których następnie załaduję dane:
create table
liczba_pracownikow(
nazwa_departamentu
varchar2(50),
liczba integer
);
create table
najwyzsze_zarobki(
nazwa_departamentu
varchar2(50),
kwota number
);
create table
najnizsze_zarobki(
nazwa_departamentu
varchar2(50),
kwota number
);
create table
srednie_zarobki(
nazwa_departamentu
varchar2(50),
kwota number
);
Mógłbym teraz zastosować kilka
osobnych insertów w taki sposób:
insert into
liczba_pracownikow select department_name,count(*)
from employees
join departments using(department_id) group by department_name;
insert into
najwyzsze_zarobki select department_name,max(salary)
from employees
join departments using(department_id) group by department_name;
insert into
najnizsze_zarobki select department_name,min(salary)
from employees
join departments using(department_id) group by department_name;
insert into
srednie_zarobki select department_name,round(avg(salary))
from employees
join departments using(department_id) group by department_name;
Jednak ma to zasadnicze wady:
- Robiąc kilka insertów na podstawie zapytań, doprowadzam do wielokrotnych skanów tabeli źródłowej. To problematyczne i nieefektywne przy dużych tabelach.
- Pomiędzy poszczególnymi insertami dane w tabeli źródłowej mogą ulec zmianie, więc efekty mogą być niespójneZamiast wielu insertów, możemy zrobić jeden insert wielotabelowy:
insert allinto liczba_pracownikow(nazwa_departamentu,liczba) values(department_name,liczba)into najwyzsze_zarobki(nazwa_departamentu,kwota) values(department_name,maksi)into najnizsze_zarobki(nazwa_departamentu,kwota) values(department_name, mini)into srednie_zarobki(nazwa_departamentu,kwota) values(department_name,srednia)select department_name,count(*) liczba, max(salary) maksi, min(salary) mini,round(avg(salary)) sredniafrom employees join departments using(department_id) group by department_name;
W tym przypadku, skan po tabeli źródłowej wykonywany jest raz, a odczytane dane są rozbijane po czterech tabelach na raz. Ponadto dane pozostają spójne. Przyjrzyjmy się planowi wykonania zapytania:
Brak komentarzy:
Prześlij komentarz