Oracle
 sql >> Base de données >  >> RDS >> Oracle

Comment représenter la division relationnelle (expression d'algèbre de base) en termes de SQL

Soit ce DDL pour les tables correspondant à vos relations pertinentes :

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

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

Vous pouvez translittérer la formule de division (3) en syntaxe Oracle SQL assez simplement, bien qu'elle soit détaillée :

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

Comme spécifié, cela utilise uniquement le CROSS JOIN et MINUS opérations, de manière à correspondre directement à la formule d'algèbre relationnelle. Dans une application de base de données réelle, cependant, on obtiendrait sûrement le même résultat via une requête totalement différente.

Notez également que les bases de données SQL peuvent violer et violent le principe de l'algèbre relationnelle formelle selon lequel les relations ne contiennent pas de tuples en double. C'est la raison de SELECT DISTINCT dans la première sous-requête. Une sélection distincte appliquée stratégiquement ailleurs dans la requête pourrait la rendre plus efficace, mais n'altérerait pas le résultat.