Biorąc pod uwagę to DDL dla tabel odpowiadających twoim odpowiednim relacjom:
create table Boats(
bid int,
bname varchar(50),
color varchar(50)
);
create table Reserves(
sid int,
bid int,
day date
);
Formułę dzielenia (3) można transliterować na składnię Oracle SQL dość prosto, chociaż jest ona pełna:
-- All sailors who reserved at least one boat
SELECT DISTINCT sid
FROM Reserves
MINUS
-- All sailors who reserved at least one boat, but not all of them
SELECT sid
FROM (
-- all combinations of a sailor who reserved any boat with any boat
-- available to be reserved:
SELECT Reserves.sid, Boats.bid
FROM
Reserves
CROSS JOIN
Boats
MINUS
-- all combinations of sailor and boat for actual reservations made
SELECT sid, bid
FROM Reserves
) sids
Jak określono, używa tylko CROSS JOIN
i MINUS
operacje, tak aby odpowiadały bezpośrednio wzorowi algebry relacyjnej. Jednak w rzeczywistej aplikacji bazodanowej z pewnością uzyskalibyśmy ten sam wynik za pomocą zupełnie innego zapytania.
Zauważ również, że bazy danych SQL mogą i naruszają zasadę formalnej algebry relacyjnej, że relacje nie zawierają duplikatów krotek. To jest powód, dla którego SELECT DISTINCT
w pierwszym podzapytaniu. Odrębny wybór zastosowany strategicznie w innym miejscu zapytania może zwiększyć jego wydajność, ale nie zmieni wyniku.