Oracle
 sql >> Database >  >> RDS >> Oracle

Come rappresentare la divisione relazionale (espressione di algebra di base) in termini di SQL

Dato questo DDL per le tabelle corrispondenti alle tue relazioni rilevanti:

create table Boats(
  bid int,
  bname varchar(50),
  color varchar(50)
);

create table Reserves(
  sid int,
  bid int,
  day date
);

Puoi traslitterare la formula di divisione (3) nella sintassi Oracle SQL in modo abbastanza semplice, sebbene sia dettagliata:

-- 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

Come specificato, utilizza solo il CROSS JOIN e MINUS operazioni, in modo da corrispondere direttamente alla formula dell'algebra relazionale. In un'applicazione di database del mondo reale, tuttavia, si otterrebbe sicuramente lo stesso risultato tramite una query completamente diversa.

Si noti inoltre che i database SQL possono violare e violano il principio dell'algebra relazionale formale secondo cui le relazioni non contengono tuple duplicate. Questo è il motivo di SELECT DISTINCT nella prima sottoquery. Una selezione distinta applicata strategicamente altrove nella query potrebbe renderla più efficiente, ma non alterare il risultato.