如何在关系数据库表上将SQL转换为关系代数
共有三个表格:如何在关系数据库表上将SQL转换为关系代数,sql,sql-server-2008,relational-database,relational-algebra,Sql,Sql Server 2008,Relational Database,Relational Algebra,共有三个表格:学生、课程和成绩 sid、cid和sid-cid(超级键)是每个表的主键 学生: sid sname address ----------------- S1 Adam Abawama S2 Mery Ignora S3 Aisha Icterra S4 Sello Icterra S5 Mery Kaysers 课程: cid cname dept ------------------ C1 Db Ceng C2 Prog Ceng
学生
、课程
和成绩
sid
、cid
和sid-cid
(超级键)是每个表的主键
学生
:
sid sname address
-----------------
S1 Adam Abawama
S2 Mery Ignora
S3 Aisha Icterra
S4 Sello Icterra
S5 Mery Kaysers
课程
:
cid cname dept
------------------
C1 Db Ceng
C2 Prog Ceng
C3 Calculus Math
C4 Stat EE
C5 Alg Ceng
sid cid grade
--------------
S1 C1 50
S1 C2 85
S1 C3 60
S1 C4 90
S1 C5 50
S2 C1 30
S2 C2 40
S3 C2 85
S4 C2 80
S4 C4 75
S4 C5 60
等级
:
cid cname dept
------------------
C1 Db Ceng
C2 Prog Ceng
C3 Calculus Math
C4 Stat EE
C5 Alg Ceng
sid cid grade
--------------
S1 C1 50
S1 C2 85
S1 C3 60
S1 C4 90
S1 C5 50
S2 C1 30
S2 C2 40
S3 C2 85
S4 C2 80
S4 C4 75
S4 C5 60
问题
ceng
和EE
课程的学生姓名数据库中获得最高分数的学生的sid
SELECT s.sname
FROM Students s
JOIN Grades g ON s.sid = g.sid
JOIN Courses c ON g.sid = c.sid
AND c.dept IN ("Ceng","EE")
第二季度我的SQL答案
SELECT sid
FROM Grades
WHERE grade =
(SELECT max(grade)
FROM Grades
GROUP BY cid HAVING Grades.cid = "C1")
答案1是返回错误的结果,如何修复它?
如何为这些命令编写关系代数?要深入了解,您可以阅读作者提供的“数据库系统概念”或免费幻灯片 使用以下命令:
SELECT s.sname
FROM Students s
JOIN Grades g ON s.sid = g.sid
JOIN Courses c ON g.cid = c.cid
WHERE c.dept = 'Ceng'
INTERSECT
SELECT s.sid
FROM Students s
JOIN Grades g ON s.sid = g.sid
JOIN Courses c ON g.cid = c.cid
WHERE c.dept = 'EE';
另一种方法是使用两个相关的子查询,如下所示:
select S.SNAME
from STUDENTS S
where exists (select G1.SID
from GRADES G1 inner join COURSES C1 on G1.CID=C1.CID
where G1.SID = S.SID
and C1.DEPT = 'Ceng')
and exists (select G2.SID
from GRADES G2 inner join COURSES C2 on G2.CID=C2.CID
where G2.SID = S.SID
and C2.DEPT = 'EE')
请参阅:我喜欢使用TDQD-测试驱动的查询设计。您可以分阶段建立查询,验证每个阶段。这是一个相当简单的查询-它只需要两个步骤(尽管我已经将两个步骤压缩到了步骤2中) 第一步 您需要以某种形状或形式进行自连接。此查询列出了在EE课程中取得成绩的学生(按sid分类):
SELECT g.sid
FROM Grades AS g
JOIN Courses AS c ON g.cid = c.cid AND c.dept = "EE"
步骤2
您可以将步骤1中的查询用作一个子查询,并使用“Ceng”的类似子查询生成两个“表”,其中包含执行EE和Ceng的学生列表;您将这些表格连接起来,找出同时进行EE和Ceng的学生,并将其与学生表格连接起来,列出他们的姓名:
SELECT s.name
FROM Students AS s
JOIN (SELECT DISTINCT g.sid
FROM Grades AS g
JOIN Courses AS c ON g.cid = c.cid AND c.dept = "EE"
) AS ee
ON s.sid = ee.sid
JOIN (SELECT DISTINCT g.sid
FROM Grades AS g
JOIN Courses AS c ON g.cid = c.cid AND c.dept = "Ceng"
) AS ceng
ON s.sid = ceng.sid
如果一些学生参加2个EE和1个Ceng课程,则需要使用不同的限定符;它可以防止它们在输出中出现两次。当然,您也可以将DISTINCT放在主查询选择列表中。结果必须是;S1和S4,但结果集是错误的。哦,我没有注意到“两者”,好的,我会相应地编辑我的答案。呵呵,也许我们可以更正为s.sid写入s.sname。选择s.sid。。。因为我们需要名字:)@DjMix-当然你应该,我这样做了,因为我想给你看S1和S4。另外,我从第二季度的SQL答案中得到了双倍的结果,我必须写不同的关键字吗?@DjMix-对于第二季度,是的,你需要
不同的
,因为成绩
每门课程都有一个相同的学生ID。如果学生在每门课程中都得到相同的分数,那么你会看到该学生的ID在每门课程中出现一次!