oracle 如何用SQL表示关系除法(基本代数表达式)

hsgswve4  于 2023-11-17  发布在  Oracle
关注(0)|答案(2)|浏览(126)

Query:查找已预订所有船只的水手的姓名
这可以在关系代数中表示为:

  1. πsname ( ((σsid,bid Reserves) / (σbid Boats)) ⋈ Sailors)
    根据关系代数,除法也可以使用基本代数运算符表示如下:
  2. A/B= πx(A) - πx((πx(A) * B) - A )
    因此,如果I convert语句1按照语句2,则
  3. Reserves/Boats= πsid(Reserves) - πsid(( πbid(Reserves) * Boats) - Reserves )
    我如何用SQL来表示Statement 3,就像在关系代数中一样(即不使用minus/Except(-) and Cross join(*)以外的任何运算符)。
    我试图在不使用NOT EXISTS and EXISTS条件的情况下实现它。
    表的模式如下:
    Sailors(sid:integer,sname:string,rating:integer,age:真实的)
    Boats(bid:integer,bname:string,color:string)
    Reserves(sid:integer,bid:integer,day:date)
dwthyt8l

dwthyt8l1#

对于与您的相关关系对应的表,给出以下命令:

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

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

字符串
您可以相当直接地将除法公式(3)翻译成Oracle SQL语法,尽管它很冗长:

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


正如所指定的那样,它只使用CROSS JOINMINUS操作,以便直接对应于关系代数公式。然而,在现实世界的数据库应用程序中,人们肯定会通过完全不同的查询获得相同的结果。
还要注意的是,SQL数据库可能并且确实违反了形式关系代数的原则,即关系不包含重复的元组。这就是第一个子查询中使用SELECT DISTINCT的原因。在查询的其他地方策略性地应用不同的选择可能会使其更有效,但不会改变结果。

nbnkbykc

nbnkbykc2#

查询将是:

select 
  sailors.sname 
from (
  select r.sid 
    from reserves r 
   group by r.sid
   having count(distinct r.bid) = (select count(*) from boats) ) fullRes
join sailors 
on sailors.sid = fullRes.sid

字符串
你可以在这里测试:
例如

相关问题