02_SELECT - Instytut Informatyki Politechniki Poznańskiej

Download Report

Transcript 02_SELECT - Instytut Informatyki Politechniki Poznańskiej

Rozdział 2: Język bazy danych - SQL
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Wprowadzenie do języka SQL
• język dostępu do bazy danych
• język deklaratywny
• grupy poleceń języka:
– DQL (ang. Data Query Language)
– DML (ang. Data Manipulation Language)
– DDL (ang. Data Definition Language)
– DCL (ang. Data Control Language)
• polecenie SQL może być zapisane:
– w jednym bądź wielu wierszach
– dużymi lub małymi literami
• polecenie SQL kończymy średnikiem
SELECT * FROM
pracownicy;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Projekcja
• wybór wartości określonych atrybutów relacji
SELECT nazwisko, etat
FROM pracownicy;
Wyrażenia arytmetyczne
• operatory arytmetyczne
– +, -, *, /
SELECT nazwisko, placa_pod*12, placa_dod+200
FROM pracownicy;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Aliasy atrybutów relacji
• alias - alternatywna nazwa atrybutu
SELECT nazwisko,
placa_pod*12 roczna_placa,
placa_dod+200 "nowe dodatki"
FROM pracownicy;
Operator konkatenacji - ||
• umożliwia łączenie wartości wyświetlanych
atrybutów
SELECT 'Pracownik ' || nazwisko
FROM pracownicy;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Obsługa wartości pustych
• funkcja NVL o następującej specyfikacji
NVL (wyrażenie, wartość)
SELECT nazwisko,
placa_pod*12 + placa_dod
FROM pracownicy;
SELECT nazwisko,
placa_pod*12 + NVL (placa_dod, 0)
FROM pracownicy;
Eliminowanie duplikatów
• słowo kluczowe DISTINCT
SELECT etat FROM pracownicy;
SELECT DISTINCT etat FROM pracownicy;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Edycja poleceń
input tekst
rozszerza bufor o wiersz tekst
change /stary/nowy
zamienia łańcuch znaków stary na
nowy w bieżącym wierszu bufora
list
wyświetla zawartość bufora
list n
wyświetla wiersz bufora o numerze n
del
kasuje bieżący wiersz bufora poleceń
run
wyświetla i wykonuje polecenie
przechowywane w buforze
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Edycja poleceń cd.
save nazwa_pliku
zapisuje zawartość bufora w pliku tekstowym
get nazwa_pliku
wczytuje do bufora zawartość pliku
edit
umożliwia edycję zawartości bufora za pomocą
edytora tekstowego (zmienna _EDITOR)
start nazwa_pliku
wykonuje polecenia zawarte w pliku
@nazwa_pliku
wykonuje polecenia zawarte w pliku
describe nazwa_relacji
wyświetla schemat relacji
exit
kończy sesję użytkownika
spool nazwa_pliku
zapisuje w pliku informacje pojawiające się na
ekranie
spool off
kończy zapisywanie do pliku
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Porządkowanie wyników zapytania
• klauzula ORDER BY
• kolejność sortowania - słowo kluczowe ASC lub DESC
• ORDER BY występuje zawsze jako ostatnia klauzula
zapytania
SELECT nazwisko, etat
FROM pracownicy
ORDER BY etat DESC, nazwisko ASC;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Selekcja krotek relacji
• klauzula WHERE
• składnia polecenia
SELECT atrybut1, atrybut2, ...
FROM relacja
WHERE atrybutm operator wartość
Operatory
• operatory matematyczne
=,
!=,
<>,
>,
>=,
SELECT nazwisko, placa_pod, etat
FROM pracownicy
WHERE placa_pod > 400;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
<,
<=
Operatory cd.
• operatory SQL
– BETWEEN ... AND ...
SELECT nazwisko, placa_pod, etat
FROM pracownicy
WHERE placa_pod BETWEEN 900 AND 1200;
– IN
SELECT nazwisko, placa_pod, id_zesp
FROM pracownicy
WHERE etat IN ('PROFESOR', 'DYREKTOR');
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Operatory cd.
– LIKE
SELECT nazwisko, placa_pod, id_zesp
FROM pracownicy
WHERE nazwisko LIKE 'M%';
– IS NULL
SELECT nazwisko, placa_pod
FROM pracownicy
WHERE placa_dod IS NULL;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Operatory cd.
• negacje operatorów SQL
– NOT BETWEEN ... AND ...
– NOT IN
– NOT LIKE
– IS NOT NULL
SELECT nazwisko, placa_pod, id_zesp
FROM pracownicy
WHERE etat NOT IN ('PROFESOR', 'DYREKTOR');
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Warunki złożone klauzuli WHERE
• operatory logiczne w klauzuli WHERE
– AND
– OR
SELECT nazwisko, placa_pod, id_zesp
FROM pracownicy
WHERE etat = 'ASYSTENT'
AND placa_pod > 400;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Warunki złożone klauzuli WHERE cd.
• operatory logiczne mogą być stosowane jednocześnie w tej
samej klauzuli WHERE
• AND posiada wyższy priorytet niż OR
• zmiana priorytetu jest możliwa za pomocą nawiasów
SELECT nazwisko, etat
FROM pracownicy
WHERE placa_pod > 500 AND etat = 'ADIUNKT'
OR etat = 'ASYSTENT';
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania
2-1.
Wyświetl wszystkich pracowników o zarobkach z
przedziału <300,800>.
select nazwisko, id_zesp, placa_pod
from pracownicy
where placa_pod between 300 and 800;
2-2.
Wyświetl całość informacji o pracownikach zespołów 10
i 20, zgodnie z alfabetycznym porządkiem nazwisk.
select * from pracownicy
where id_zesp in (10, 20)
order by nazwisko;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-3.
Wyświetl wszystkich pracowników o nazwiskach
rozpoczynających się od liter KO i JE.
select nazwisko
from pracownicy
where nazwisko like 'KO%' or nazwisko like 'JE%';
2-4.
Wyświetl nazwiska, etaty i płace podstawowe
pracowników , którzy mają przełożonych.
select nazwisko, etat, placa_pod
from pracownicy
where id_szefa is not null;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-5.
Wyświetl nazwiska i etaty wszystkich asystentów
zespołu 20 w porządku leksykograficznym nazwisk.
select nazwisko, etat
from pracownicy
where etat='ASYSTENT' and id_zesp=20
order by nazwisko asc;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-6.
Wyświetl nazwiska i roczne wynagrodzenie wszystkich
pracowników zatrudnionych w roku 1992 i 1993,
w kolejności malejącego wynagrodzenia.
PRACOWNIK
----------------------------------HAPKE(ASYSTENT)
JEZIERSKI (ASYSTENT)
.........................................
ROCZNE_ZAROBKI
---------------------------6840
6242.4
...........
select nazwisko||' ('||etat||')' pracownik,
12*(placa_pod+nvl(placa_dod,0)) roczne_zarobki
from pracownicy
where zatrudniony like '%92' or zatrudniony like '%93'
order by 2 desc;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Funkcje grupowe
• operują na podzbiorach krotek relacji, nazywanych grupami
• wyznaczają wartość operując na atrybutach wielu krotek
• funkcje:
– avg ([distinct|all] wyrażenie)
– count ([distinct|all] wyrażenie)
– max ([distinct|all] wyrażenie)
SELECT AVG(placa_pod)
– min ([distinct|all] wyrażenie)
FROM pracownicy;
– sum ([distinct|all] wyrażenie)
SELECT count(*)
FROM pracownicy
WHERE id_zesp=20;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Podział krotek na grupy - klauzula GROUP BY
• wyznacz średnie płace w każdej z grup zespołowych
SELECT id_zesp, avg(placa_pod)
FROM pracownicy
GROUP BY id_zesp;
Podział grup na podgrupy
• wyznacz średnie płace w każdej z grup etatowych dla
poszczególnych zespołów
SELECT id_zesp, etat, avg(placa_pod)
FROM pracownicy
GROUP BY id_zesp, etat;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Klauzula HAVING
• wybór grup spełniających określone warunki
• wyświetl grupy etatowe, których suma płac podstawowych
przekracza 4000 PLN
SELECT etat, sum(placa_pod)
FROM pracownicy
GROUP BY etat
HAVING sum(placa_pod) > 4000;
• wyświetl maksymalne płace w ramach grup
etatowych, z pominięciem grupy adiunktów
SELECT etat, max(placa_pod)
FROM pracownicy
WHERE etat != 'ADIUNKT'
GROUP BY etat;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania
2-7.
Wyświetl liczbę pracowników zatrudnionych na etacie
profesora.
select count(*) profesorowie
from pracownicy
where etat='PROFESOR';
2-8.
Wyświetl przeciętną, miesięczną płacę oraz przeciętne
roczne zarobki każdej grupy etatowej (uwzględnij płacę
dodatkową).
select etat,
avg(placa_pod) srednia_placa_pod,
avg(12*(placa_pod+nvl(placa_dod,0))) roczne_zarobki
from pracownicy
group by etat;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-9.
Wyświetl numery zespołów zatrudniających powyżej 3
pracowników.
select id_zesp, count(*) liczba_pracownikow
from pracownicy
group by id_zesp
having count(*)>3;
2-10. Sprawdź, czy wszystkie numery pracowników są
unikalne.
select id_prac
from pracownicy
group by id_prac
having count(*)>1;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-11. Dla każdego szefa wyświetl płacę najmniej
zarabiającego podwładnego. Pomiń grupy, w których
minimalna płaca jest niższa od 300 zł. Uporządkuj
wyniki według malejących zarobków.
select id_szefa, min(placa_pod)
from pracownicy
group by id_szefa
having min(placa_pod)>300
order by min(placa_pod) desc;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Połączenie równościowe
PRACOWNICY
id_prac nazwisko
180
200
210
MAREK
ZAKRZEWICZ
BIAŁY
id_zesp
10
30
30
ZESPOLY
id_zes
p
10
30
SELECT nazwisko, z.id_zesp, nazwa
FROM pracownicy p, zespoly z
WHERE p.id_zesp = z.id_zesp;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
nazw
a
ADMINISTRACJA
SYSTEMY EKSPERCKIE
Połączenie nierównościowe
PRACOWNICY
id_prac nazwisko
180
200
MAREK
ZAKRZEWICZ
placa_pod
410.2
208
ETATY
nazwa
placa_mi
n
SEKRETARKA
270 270
STAŻYSTA
150
placa_ma
x
450
250
SELECT nazwisko, nazwa
FROM pracownicy, etaty
WHERE placa_pod BETWEEN placa_min AND placa_max;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Połączenie zewnętrzne
SELECT z.id_zesp, z.nazwa, p.nazwisko
FROM pracownicy p, zespoly z
WHERE p.id_zesp = z.id_zesp;
Zespół 50 - BADANIA OPERACYJNE nie zostanie
wyświetlony
Zadanie: wyświetlić wszystkie zespoły, nawet te, które nie
zatrudniają pracowników
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Połączenie zewnętrzne cd.
id_zesp
10
20
50
nazwa
ADMINISTRACJA
SYSTEMY ROZPROSZONE
BADANIA OPERACYJNE
nazwisko
MAREK
10
JEZIERSKI
20
KONOPKA
20
???
SELECT z.id_zesp, z.nazwa, p.nazwisko
FROM pracownicy p, zespoly z
WHERE p.id_zesp (+) = z.id_zesp;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
id_zesp
Połączenie zewnętrzne cd.
id_zesp
10
20
nazwa
nazwisko
ADMINISTRACJA
SYSTEMY ROZPORSZONE
???
MAREK
10
JEZIERSKI
20
KONOPKA
20
KIWLENKO
SELECT z.id_zesp, z.nazwa, p.nazwisko
FROM pracownicy p, zespoly z
WHERE p.id_zesp = z.id_zesp (+);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
id_zesp
Połączenie zwrotne relacji
Pracownicy
id_prac
130
140
190
nazwisko
id_szefa
BRZEZIŃSKI
MORZY
MATYSIAK
100
130
140
P
id_prac
130
140
190
S
nazwisko
id_szefa
BRZEZIŃSKI
MORZY
MATYSIAK
100
130
140
id_prac
130
140
190
nazwisko
id_szefa
BRZEZIŃSKI
MORZY
MATYSIAK
100
130
140
SELECT p.nazwisko, s.nazwisko
FROM pracownicy p, pracownicy s
WHERE p.id_szefa = s.id_prac;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania
2-12. Wyświetl wszystkich pracowników z ul. Piotrowo 3a;
wyniki uporządkuj według nazwisk pracowników.
select nazwisko, adres from pracownicy p, zespoly z
where (z.adres = 'PIOTROWO 3A') and
(p.id_zesp = z.id_zesp)
order by nazwisko;
2-13. Wyświetl nazwiska, miejsca pracy oraz nazwy zespołów
tych pracowników, których miesięczna pensja
przekracza 400.
select nazwisko, adres, nazwa
from pracownicy p, zespoly z
where(placa_pod > 400) and
(p.id_zesp = z.id_zesp);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-14. Wyświetl nazwiska, etaty, wynagrodzenia, kategorie
płacowe i nazwy zespołów pracowników nie będących
asystentami. Wyniki uszereguj zgodnie z malejącym
wynagrodzeniem.
select nazwisko, etat, placa_pod,
e.nazwa kategoria, z.nazwa zespol
from pracownicy p, etaty e, zespoly z
where (etat <> 'ASYSTENT') and
(p.id_zesp = z.id_zesp) and
(placa_pod between placa_min and
placa_max)
order by placa_pod desc;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-15. Wyświetl zespoły nie zatrudniające pracowników.
select z.nazwa zespol
from pracownicy p, zespoly z
where (p.id_zesp(+) = z.id_zesp) and
(p.id_prac is null);
2-16. Wyświetl nazwiska i numery pracowników wraz z
numerami i nazwiskami ich szefów.
select p.id_prac, p.nazwisko podwladny, s.id_prac,
s.nazwisko szef
from pracownicy p, pracownicy s
where p.id_szefa = s.id_prac;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-17. W zleceniu z powyższego zadania dokonaj modyfikacji
umożliwiających wyświetlenie pracownika WĘGLARZ,
który nie ma szefa.
select p.id_prac, p.nazwisko podwladny, s.id_prac,
s.nazwisko szef
from pracownicy p, pracownicy s
where p.id_szefa = s.id_prac(+);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Operatory zbiorowe
• UNION
– suma zbiorów
– eliminuje duplikaty
• UNION ALL
– suma zbiorów
– nie eliminuje duplikatów
• INTERSECT
– część wspólna zbiorów
– eliminuje duplikaty
• MINUS
– różnica zbiorów
– eliminuje duplikaty
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
SELECT etat
FROM pracownicy
WHERE id_zesp = 10
UNION
SELECT etat
FROM pracownicy
WHERE id_zesp = 30;
ORDER BY 1;
Reguły stosowania operatorów zbiorowych
• w łączonych operatorami zbiorowymi klauzulach SELECT
musi wystąpić ta sama liczba atrybutów
• typy odpowiednich atrybutów różnych klauzul SELECT
muszą być zgodne
• w wyniku zapytania pojawiają się
wyłącznie z pierwszej klauzuli SELECT
nazwy
atrybutów
• klauzula ORDER BY może być użyta tylko jako ostatnia
klauzula zapytania
• w klauzuli ORDER BY nie stosujemy nazw atrybutów lecz
ich numery porządkowe
• polecenia SELECT są wykonywane w kolejności ich
wystąpienia (od góry do dołu)
• nawiasy umożliwiają zmianę domyślnej kolejności
wykonywania łączonych operatorami zbiorowymi poleceń
SELECT
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania
2-18. Znajdź etat, na którym zatrudniono pracownika w
drugiej połowie 93r. oraz w drugiej połowie 94 r.
select etat
from pracownicy
where zatrudniony
between '01-JUL-93' and '31-DEC-93'
intersect
select etat
from pracownicy
where zatrudniony
between '01-JUL-94' and '31-DEC-94';
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-19. Korzystając z operatorów zbiorowych, wyświetl zespoły
niezatrudniające pracowników.
select z.id_zesp, z.nazwa
from pracownicy p, zespoly z
where p.id_zesp(+)=z.id_zesp
minus
select z.id_zesp, z.nazwa
from pracownicy p, zespoly z
where p.id_zesp=z.id_zesp;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Podzapytania
• podzapytanie jest poleceniem SELECT zagnieżdżonym w
innym poleceniu SELECT
• ogólny format zagnieżdżania zapytań:
SELECT atrybut1, atrybut2, ...
FROM relacja
WHERE atrybut operator (SELECT atrybut
FROM relacja
WHERE warunek);
• operator
 =, !=, <>, >, >=, <, <=
 IN
 ANY, ALL
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Reguły zagnieżdżania podzapytań
• podzapytanie ograniczamy nawiasami i zagnieżdżamy po
prawej stronie warunku zapytania zewnętrznego;
• w podzapytaniu nie używamy klauzuli ORDER BY;
• klauzula ORDER BY może wystąpić wyłącznie jako ostatnia
klauzula najbardziej zewnętrznego zapytania;
• liczba oraz typy atrybutów występujących w klauzuli
SELECT podzapytania musi być zgodna z liczbą i typem
atrybutów użytych w warunku zapytania zewnętrznego, tj.
zapytania wyższego poziomu zagnieżdżenia;
• w podzapytaniu można używać operatorów zbiorowych;
• podzapytania są zawsze wykonywane w kolejności od
najgłębiej zagnieżdżonego do najbardziej zewnętrznego.
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Podzapytania wyznaczające jedną krotkę
• wyznacz pracownika zarabiającego najmniej
SELECT nazwisko, etat, placa_pod
FROM pracownicy
WHERE placa_pod = (SELECT MIN(placa_pod)
FROM pracownicy);
• wyznacz pracownika zarabiającego najmniej w swoim
zespole
SELECT nazwisko, etat, placa_pod
FROM pracownicy
WHERE (placa_pod, id_zesp) IN
(SELECT MIN(placa_pod), id_zesp
FROM pracownicy
GROUP BY id_zesp);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Podzapytania wyznaczające wiele krotek cd.
• operator ANY
SELECT nazwisko, placa_pod, etat, id_zesp FROM pracownicy
WHERE placa_pod > ANY (SELECT DISTINCT placa_pod
FROM pracownicy
WHERE id_zesp = 30);
• operator ALL
SELECT nazwisko, placa_pod, etat, id_zesp FROM pracownicy
WHERE placa_pod > ALL (SELECT DISTINCT placa_pod
FROM pracownicy
WHERE id_zesp = 30);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Podzapytania w klauzuli HAVING
• wyświetl te zespoły, w których średnia płaca podstawowa
jest większa niż średnia płaca w zespole trzydziestym
SELECT id_zesp, AVG (placa_pod) FROM pracownicy
HAVING AVG (placa_pod) > (SELECT AVG (placa_pod)
FROM pracownicy
WHERE id_zesp = 30)
GROUP BY id_zesp;
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Wielopoziomowe zagnieżdżanie zapytań
• wyświetlić nazwiska i płace pracowników, zarabiających
więcej niż wynosi maksymalna płaca w zespole o nazwie
ALGORYTMY
SELECT nazwisko, placa_pod
FROM pracownicy
WHERE placa_pod >
(SELECT MAX (placa_pod)
FROM pracownicy
WHERE id_zesp =
(SELECT id_zesp
FROM zespoly
WHERE nazwa ='ALGORYTMY'));
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania
2-20. Wyświetl najkrócej pracujących pracowników każdego
zespołu. Uszereguj wyniki zgodnie z kolejnością zatrudnienia.
select id_zesp, nazwisko, zatrudniony from pracownicy
where (id_zesp, zatrudniony) in
(select id_zesp, max(zatrudniony)
from pracownicy
group by id_zesp)
order by zatrudniony;
2-21. Wyświetl zespoły, które nie zatrudniają pracowników.
select id_zesp from zespoly z
where id_zesp not in (select distinct id_zesp
from pracownicy);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Zadania cd.
2-22. Wyświetl identyfikator i nazwę zespołu wypłacającego
swoim pracownikom najwięcej pieniędzy miesięcznie.
select id_zesp, nazwa
from zespoly
where id_zesp=
(select id_zesp from pracownicy
group by id_zesp
having sum(placa_pod)=
(select max(sum(placa_pod))
from pracownicy
group by id_zesp) );
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Podzapytania skorelowane
• cechy
– wykonywane dla każdej krotki przeglądanej przez
zapytanie zewnętrzne
– operują na wartościach atrybutów przekazanych przez
zapytanie zewnętrzne
• przykład:
– wyszukaj pracowników zarabiających więcej niż wynosi
średnia pensja w ich zespole
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
Podzapytania skorelowane cd.
P
Pracownicy
nazwisko placa_pod id_zesp
nazwisko placa_pod id_zesp
LECH
CZECH
RUS
PIAST
300
400
400
500
1
1
2
2
LECH
CZECH
RUS
PIAST
300
400
400
500
SELECT nazwisko, placa_pod, id_zesp
FROM pracownicy p
WHERE placa_pod >
(SELECT AVG(placa_pod) FROM pracownicy
WHERE id_zesp = p.id_zesp);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej
1
1
2
2
Podzapytania skorelowane cd.
• operator EXISTS
– umożliwia sprawdzenie czy podzapytanie wyznacza
jakąkolwiek wartość
• operator NOT EXISTS
• przykład: wyszukaj pracowników, którym służbowo
podlegają inni pracownicy
select id_prac, nazwisko, etat, id_zesp
from pracownicy p
where exists (select id_prac
from pracownicy
where id_szefa = p.id_prac);
(c) 1999, Instytut Informatyki Politechniki Poznańskiej