smc*_*mcg 3 sql aggregate relational-algebra
我编写了几个 SQL 查询,希望将其转换为关系代数。但是,一些查询使用聚合运算符,我不知道如何转换它们。值得注意的是,他们使用 COUNT 和 GROUP BY.. HAVING 运算符。
这是架构:
Sailors( sid , sname, rating) Reserves( sid , bid , price) Boats( bid , bname)
这是我正在做的一个例子:找到恰好由 2 个水手预订的所有船只的出价和名称。
SELECT B.bid, B.bname
FROM Boats B, Reserves R
WHERE B.bid = R.bid
GROUP BY R.bid
HAVING 2 = (SELECT COUNT(*)
FROM Reserves R2
WHERE R2.bid = B.bid);
允许的关系代数运算:选择、投影、连接、条件连接、重命名、并集、交集、叉积、除法
这只是一半的答案......
可以使用条件连接和投影找到关系“由两个或多个水手保留的船”,它们都在您允许的操作集中:
SELECT DISTINCT R1.bid
  FROM Reserves AS R1 
       JOIN Reserves AS R2
          ON R1.bid = R2.bid
             AND R1.sid < R2.sid;
可以使用条件连接(两次)和投影找到“三个或更多水手保留的船”关系,它们都在您允许的操作集中:
SELECT DISTINCT R1.bid
  FROM Reserves AS R1
       JOIN Reserves AS R2
          ON R1.bid = R2.bid
             AND R1.sid < R2.sid
       JOIN Reserves AS R3
          ON R1.bid = R3.bid
          AND R2.sid < R3.sid;
如果我们有一个减号运算符,例如EXCEPT在标准 SQL 中:
SELECT DISTINCT R1.bid
  FROM Reserves AS R1 
       JOIN Reserves AS R2
          ON R1.bid = R2.bid
             AND R1.sid < R2.sid
EXCEPT
SELECT DISTINCT R1.bid
  FROM Reserves AS R1
       JOIN Reserves AS R2
          ON R1.bid = R2.bid
             AND R1.sid < R2.sid
       JOIN Reserves AS R3
          ON R1.bid = R3.bid
          AND R2.sid < R3.sid;
如果我们有限制(WHERE在 SQL 中)和半差异(又名antijoin)运算符(例如NOT IN在 SQL 中):
SELECT DISTINCT R1.bid
  FROM Reserves AS R1 
       JOIN Reserves AS R2
          ON R1.bid = R2.bid
             AND R1.sid < R2.sid
 WHERE R1.bid NOT IN (
                      SELECT DISTINCT R1.bid
                        FROM Reserves AS R1
                             JOIN Reserves AS R2
                                ON R1.bid = R2.bid
                                   AND R1.sid < R2.sid
                             JOIN Reserves AS R3
                                ON R1.bid = R3.bid
                                AND R2.sid < R3.sid
                     );
...但您允许的操作集不包括限制、半差或减号:(