第3章_关系数据库标准语言(SQL)_006_由元组关系演算到SQL Command_002_案例_02_以'李力'老师教授的课程为准,学生的5种选课情况

01_查询选修了'李力'老师教授的全部课程的学生的学号、姓名;

02_查询至少有一门'李力'老师所教授的课程没有选过的学生的学号、姓名(这名学生没有选择李力老师教授的全部课程);

03_查询一门'李力'老师所教授的课程都没有选的学生的学号、姓名;

04_查询至少选修了一门'李力'老师所教授的课程的学生的学号、姓名;

05_学生只选修了'李力'老师的全部课程;

  

01_查询选修了'李力'老师教授的全部课程的学生的学号、姓名 ===》
{new_s(2) |
  ∃s(
    s(S) Λ
    ∀tc(
      tc(TC) Λ
      ∃t(
        t(T) Λ
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) → ∃sc(
          sc(SC) Λ
          s.SNo = sc.SNo Λ
          sc.CNo = tc.CNo
        )
    ) Λ
    new_s[1] = s[1] Λ
    new_s[2] = s[2]
  )
}
  
经过化简得到:
{new_s(2) |
  ∃s(
    ¬【∃tc(
        ∃t(
          t.TNo = tc.TNo Λ
          t.TN = '李力'
        ) Λ
        ¬【∃sc(
          s.SNo = sc.SNo Λ
          sc.CNo = tc.CNo
        )】
    )】
  )
}
  
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
  NOT EXISTS (
    SELECT *
    FROM TC
    WHERE
      EXISTS (
        SELECT *
        FROM T
        WHERE
          T.TN = '李力' AND
          TC.TNo = T.TNo
      )
      AND
      NOT EXISTS (
        SELECT *
        FROM SC
        WHERE
          SC.SNo = S.SNo AND
          SC.CNo = TC.CNo
      )
  )
  
  
  
02_查询至少有一门'李力'老师所教授的课程没有选过的学生的学号、姓名(这名学生没有选择李力老师教授的全部课程) ===》
{new_s(2) |
  ∃s(
    s(S) Λ
    ∃tc(
      tc(TC) Λ
      ∃t(
        t(T) Λ
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) Λ
      ∀sc ¬(
        sc(SC) Λ
        s.SNo = sc.SNo Λ
        sc.CNo = tc.CNo
      )
    ) Λ
    new_s[1] = s[1] Λ
    new_s[2] = s[2]
  )
}
  
经过化简得到:
{new_s(2) |
  ∃s(
    ∃tc(
      ∃t(
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) Λ
      ¬【∃sc (
        s.SNo = sc.SNo Λ
        sc.CNo = tc.CNo
      )】
    ) Λ
    new_s[1] = s[1] Λ
    new_s[2] = s[2]
  )
}
  
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
  EXISTS (
    SELECT *
    FROM TC
    WHERE
      EXISTS (
        SELECT *
        FROM T
        WHERE
          T.TN = '李力' AND
          TC.TNo = T.TNo
      )
    AND
    EXISTS (
      SELECT *
      FROM SC
      WHERE
        SC.SNo = S.SNo AND
        SC.CNo = TC.CNo
    )
  )
  
  
  
03_查询一门'李力'老师所教授的课程都没有选的学生的学号、姓名 ===》
{new_s(2) |
  ∃s(
    s(S) Λ
    ∀tc(
      tc(TC) Λ
      ∃t(
        t(T) Λ
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) → ∀sc ¬(
            sc(SC) Λ
            s.SNo = sc.SNo Λ
            sc.CNo = tc.CNo
          )
    ) Λ
    new_s[1] = s[1] Λ
    new_s[2] = s[2]
  )
}
  
经过化简得到:
{new_s(2) |
  ∃s(
    ¬【∃tc(
      ∃t(
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) Λ
      ∃sc(
        s.SNo = sc.SNo Λ
        sc.CNo = tc.CNo
      )
    )】
  )
}
注释:这其实就是“查询至少选修了一门'李力'老师所教授的课程的学生的学号、姓名”的否定。
  
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
  NOT EXISTS (
    SELECT *
    FROM TC
    WHERE
      EXISTS (
        SELECT *
        FROM T
        WHERE
            T.TN = '李力' AND
            TC.TNo = T.TNo
      )
      AND
      EXISTS (
        SELECT *
        FROM SC
        WHERE
          SC.SNo = S.SNo AND
          SC.CNo = TC.CNo
      )
  )
  
  
  
04_查询至少选修了一门'李力'老师所教授的课程的学生的学号、姓名 ===》
{new_s(2) |
  ∃s(
    s(S) Λ
    ∃tc(
      tc(TC) Λ
      ∃t(
        t(T) Λ
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) Λ
      ∃sc(
        sc(SC) Λ
        s.SNo = sc.SNo Λ
        sc.CNo = tc.CNo
      )
    ) Λ
    new_s[1] = s[1] Λ
    new_s[2] = s[2]
  )
}
  
经过化简得到:
{new_s(2) |
  ∃s(
    ∃tc(
      ∃t(
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) Λ
      ∃sc(
        s.SNo = sc.SNo Λ
        sc.CNo = tc.CNo
      )
    )
  )
}
注释:这里的∃t和∃sc是可以合并的,依据“量词辖域的扩张和收缩”的第一点,并且∃t和∃sc互不影响,运用2次即可写成 ===》
【∃t, p(t)) Λ (∃sc, q(sc)】  【∃t, p(t) Λ ∃sc, q(sc)】  【∃t, ∃sc, p(t) Λ q(sc)】
∃t(
  ∃sc(
    t.TNo = tc.TNo Λ
    t.TN = '李力' Λ
    s.SNo = sc.SNo Λ
    sc.CNo = tc.CNo
  )
)
进一步我们可以写成:【∃t∃sc, p(t, sc)】这样的形式(没有自由元组变元的二元谓词)。
拓展:只含有“存在量词∃”或者只含有“全称量词∀”的SQL语句中,除了最后投影的表之外,其他的表可以任意交换顺序(因为最后是要投影S表)。依据为“多重量化及其等价式和蕴含式”,【∃x∃y, p(x, y)】与【∃y∃x, p(x, y)】含义相同
全是全称量词:(p1, p2, ..., pn,两两不受对方辖域的影响,即相互之间可以看成是不受约束的自由元组变量)
(∀, ¬p1 ∀, ¬p2 ... ∀, ¬pn)
¬(∀, ¬p1 ∀, ¬p2 ... ∀, ¬pn-1) ∨ (∀, ¬pn)
¬(∀, ¬p1 → ∀, ¬p2 → ... ∀, ¬pn-1) ∨ ¬(∃, pn)
 ¬【(∀, ¬p1 ∀, ¬p2 ... ∀, ¬pn-1) Λ (∃, pn)】
......
¬【(∃, p1) Λ ... Λ (∃, pn)】
¬【∃...∃, p1 Λ ... Λ pn
  
按照简化后的“元组关系演算式”得出SQL语句:
SELECT SNo, SN
FROM S
WHERE
  EXISTS (
    SELECT *
    FROM TC
    WHERE
      EXISTS (
        SELECT *
        FROM T
        WHERE
          T.TN = '李力' AND
          TC.TNo = T.TNo
      )
      AND
      EXISTS (
        SELECT *
        FROM SC
        WHERE
          SC.SNo = S.SNo AND
          SC.CNo = TC.CNo
      )
  )
  
  
  
05_学生只选修了'李力'老师的全部课程 ===》
分析:p↔q (p→q Λ q→p) (pΛq) ∨ (¬pΛ¬q),虽然说可以进一步简化,但是在元组关系演算中我们通常使用第二个,这是因为p和q不好找。随时这样说,但是我们还是可以给出一个等价式:
¬{∃p【P(p) Λ ¬∃q【Q(q)】∃q【Q(q) Λ ¬∃p【P(p)】},按照德摩根律将{}去掉后得到 ===》

 ∀p¬【P(p) Λ ¬∃q【Q(q)】 Λ ∀q¬【Q(q) Λ ¬∃p【P(p)】:意思就是同事满足两个条件 ===》
  1. 对于任意的p,不可能在p∈P的情况下,没有一个q∈Q使得Q(q)成立;
  2. 对于任意的q,不可能在q∈Q的情况下,没有一个p∈P使得P(p)成立;
{new_s(2) |
  ∃s(
    s(S) Λ
    ∀tc(
      tc(TC) Λ
      ∃t(
        t(T) Λ
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) → ∃sc(
          sc(SC) Λ
          sc.CNo = tc.CNo Λ
          s.SNo = sc.SNo
        )
    ) Λ
    ∀sc(
      sc(SC) Λ
      s.SNo = sc.SNo → ∃tc(
                  sc.CNo = tc.CNo Λ
                  ∃t(
                    t(T) Λ
                    t.TNo = tc.TNo Λ
                    t.TN = '李力'
                  )
                )
    )
    new_s[1] = s[1] Λ
    new_s[2] = s[2]
  )
}
  
经过化简得到:
{new_s(2) |
  ∃s(
    ¬【∃tc(
      ∃t(
        t.TNo = tc.TNo Λ
        t.TN = '李力'
      ) Λ
      ¬【∃sc(
        sc.CNo = tc.CNo Λ
        s.SNo = sc.SNo
      )】
    )】 Λ
    ¬【∃sc(
      s.SNo = sc.SNo Λ
      ¬【∃tc(
        sc.CNo = tc.CNo Λ
        ∃t(
          t.TNo = tc.TNo Λ
          t.TN = '李力'
        )
      )】
    )】
  )
}
  
按照简化后的“元组关系演算式”得出SQL语句:(其中有一个变形,依据德摩根律)
SELECT SN, SNo
FROM S
WHERE NOT (
  EXISTS (
    SELECT *
    FROM TC
    WHERE
      EXISTS (
        SELECT *
        FROM T
        WHERE
          T.TNo = TC.TNo AND
          T.TN = '李力'
      ) AND
      NOT EXISTS (
        SELECT *
        FROM SC
        WHERE
          S.SNo = SC.SNo AND
          SC.CNo = TC.CNo
      )
  ) OR
  EXISTS (
    SELECT *
    FROM SC
    WHERE
      S.SNo = SC.SNo AND
      NOT EXISTS (
        SELECT *
        FROM TC
        WHERE
          SC.CNo = TC.CNo AND
          EXISTS (
            SELECT *
            FROM T
            WHERE
              T.TNo = TC.TNo AND
              T.TN = '李力'
          )
      )
  )
)

posted @ 2020-04-06 09:12  BN2U  阅读(90)  评论(0编辑  收藏