第3章_关系数据库标准语言(SQL)_006_由元组关系演算到SQL Command_002_案例_01_以全部课程为准,学生的4种选课情况
01:查询选修了全部课程的学生的学号、姓名;
02:查询至少有一门课程没有选过的学生的学号、姓名(这名学生没有选择全部课程);
03:查询一门课程都没有选的学生的学号、姓名;
04:查询至少选修了一门课程的学生的学号、姓名;
01_查询选修了全部课程的学生的学号、姓名 ===》
{new_s(2) |
∃s(
s(S) Λ
∀c(
c(C)
→ ∃sc(
sc(SC) Λ
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)
) Λ
new_s[1] = s[1] Λ
new_s[2] = s[2]
)
}
经过化简得到:
{new_s(2) |
∃s(
¬【∃c(
¬【∃sc(
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)】
)】
)
}
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
NOT EXISTS (
SELECT *
FROM C
WHERE
NOT EXISTS (
SELECT *
FROM SC
WHERE
SC.SNo = S.SNo AND
SC.CNo = C.CNo
)
)
02_查询至少有一门课程没有选过的学生的学号、姓名(这名学生没有选择全部课程) ===》
{new_s(2) |
∃s(
s(S) Λ
∃c(
c(C) Λ
∀sc ¬(
sc(SC) Λ
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)
) Λ
new_s[1] = s[1] Λ
new_s[2] = s[2]
)
}
经过化简得到:
{new_s(2) |
∃s(
∃c(
¬【∃sc (
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)】
)
)
}
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
EXISTS (
SELECT *
FROM C
WHERE
NOT EXISTS (
SELECT *
FROM SC
WHERE
SC.SNo = S.SNo AND
SC.CNo = C.CNo
)
)
注释:可以看到“查询至少有一门课程没有选过的学生的学号、姓名”与“查询选修了全部课程的学生的学号、姓名”互为否定。
03_查询一门课程都没有选的学生的学号、姓名 ===》
{new_s(2) |
∃s(
s(S) Λ
∀c(
c(C)
→ ∀sc ¬(
sc(SC) Λ
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)
) Λ
new_s[1] = s[1] Λ
new_s[2] = s[2]
)
}
经过化简得到:
{new_s(2) |
∃s(
¬【∃c(
∃sc(
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)
)】
)
}
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
NOT EXISTS (
SELECT *
FROM C
WHERE
EXISTS (
SELECT *
FROM SC
WHERE
SC.SNo = S.SNo AND
SC.CNo = C.CNo
)
)
04_查询至少选修了一门课程的学生的学号、姓名 ===》
{new_s(2) |
∃s(
s(S) Λ
∃c(
∃sc(
sc(SC) Λ
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)
) Λ
new_s[1] = s[1] Λ
new_s[2] = s[2]
)
}
经过化简得到:
{new_s(2) |
∃s(
∃c(
∃sc(
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)
)
)
}
注释:这里的∃c和∃sc是可以交换顺序的,依据为“多重量化及其等价式和蕴含式” ===》
∃c(∃sc, p(c, sc)) ⇔ ∃c∃sc, p(c, sc) ⇔ ∃sc∃c, p(c, sc) ⇔ ∃sc(∃c, p(c, sc))
∃sc(
∃c(
s.SNo = sc.SNo Λ
sc.CNo = c.CNo
)
)
拓展:在只含有“存在量词∃”或者只含有“全称量词∀”的SQL语句中,除了S表之外,其他的表可以任意交换顺序(因为最后是要投影S表)。
全是全称量词:
(∀, ¬p1 → ∀, ¬p2 → ... → ∀, ¬pn)
⇔ ¬(∀ → ∀ → ... ) ∨ (∀, ¬pn)
⇔ ¬(∀ → ∀ → ... ) ∨ ¬(∃, pn)
⇔ (∀ → ∀ → ... ) Λ (∃, pn)
......
⇔ ¬【(∃, p1) Λ ... Λ (∃, pn)】
⇔ ¬【∃...∃, p1 Λ ... Λ pn】
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
EXISTS (
SELECT *
FROM C
WHERE
EXISTS (
SELECT *
FROM SC
WHERE
SC.SNo = S.SNo AND
SC.CNo = C.CNo
)
)
注释:这其实就是“查询一门课程都没有选修的学生的学号、姓名”的否定。