我们目前正在研究有关数据库的讲座,我们不确定我们的解决方案是否是解决此类问题的正确方法。
相关关系的翻译:
任务是找到具有相同主题(“ Gebieet”)的成对讲座(“ Vorlesung”)。结果表应包含两个讲座的名称(“ VTitel”)和共享主题的名称(“ Titel”)。
我们想出的解决方案是
SELECT "T1"."VTitel", "T2"."VTitel", "T1"."Titel"
FROM (SELECT v1."VTitel", "Titel" FROM "Vorlesung" v1 NATURAL JOIN "VG" g) AS "T1"
JOIN (SELECT v1."VTitel", "Titel" FROM "Vorlesung" v1 NATURAL JOIN "VG" g) AS "T2"
ON "T1"."Titel" = "T2"."Titel" AND "T1"."VTitel" <> "T2"."VTitel";
这是解决此问题的正确方法,还是有更简单的方法来解决此问题?
看起来它将为您提供正确的答案,但是在实践中,它通常会更快(并且通常,尽管并不总是更具可读性),以避免嵌套子查询。我假设您已经进行过有关关系代数的讲座,因此您会注意到,如果将查询转换为关系形式,结果会相当长(我重命名了表和列,并使用此站点生成了它,但是您应该自己手动完成; S是Vorlesung,T是VG,b和d是每个表中的两个字段):
π T1.b, T2.b, T1.d ρ T1 ( π v1.b, v1.d ρ v1 S ⨝ ρ g T) ⨝ T1.d = T2.d and T1.b ≠ T2.b ρ T2 ( π v1.b, v1.d ρ v1 S ⨝ ρ g T)
这将使用12个运算符。与其在联接内部没有选择,不如您只是想将表的所有实例重命名为不同的名称,然后将它们全部联接在一起!
SELECT V1.VTitel,
V2.VTitel,
VG1.Titel
FROM Vorlesung AS V1
JOIN VG AS VG1
ON VG1.VNummer = V1.VNummer
JOIN Vorlesung AS V2
ON V1.VTitel <> V2.VTitel
JOIN VG AS VG2
ON VG2.VNummer = V2.VNummer
WHERE VG2.Titel = VG1.Titel
这使我们可以更轻松地管理9个操作员:
π V1.b, V2.b, V1.d σ VG1.b = VG2.b ρ V1 S ⨝ VG1.d = V1.d ρ VG1 T ⨝ V1.b ≠ V2.b ρ V2 S ⨝ VG2.d = V2.d ρ VG2 T
注意,我摆脱了自然联接,因此我们不必担心方括号等;自然连接在现实生活中也是一件可怕的事情,但在理论上是有道理的。这是一个很好的练习,看看是否可以使用自然联接重写新查询,以及是否可以在不使用where子句的情况下再次编写它,是否能理解我的工作!
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句