3

経済学などの専攻を考えてみましょう。ある学生が、その専攻を卒業するために「EC 101」または「EC 102」のいずれかを取得する必要があるが、必ずしも両方を取得する必要はないとします。現在、次のような2つのテーブルがあります。

コース: CourseID、CourseName

専攻: MajorID、MajorName、RequiredCourseID

データベース設計において、コース A またはコース B のいずれかを受講する必要があるが、必ずしも両方を受講するとは限らないという、専攻の要件が時々あるという要件をどのように捉えることができますか?

4

2 に答える 2

2

専攻には要件があり、要件はコースによって満たすことができます。このようにして、専攻は共通の要件を共有することもできます。

major  requirementId
-----------------------
econ       1
econ       2
artOrSmth  2


requirementId     coursename
------------------------------
    1              econ101
    1              econ102
    2              math101
于 2013-03-15T15:39:32.950 に答える
2

スキーマ設計

テーブルをリファクタリングし、追加のテーブルをいくつか導入する必要があります。

  • コース: CourseID、CourseName

  • Majors: MajorID、MajorName

  • MajorRequirements: MajorID、ReqId

  • 要件: ReqId、ReqCount

  • RequiredCourseOptions: ReqId、CourseID

サンプルデータ

質問から:

経済学 (EC001): 学生がその専攻を卒業するために「EC 101」または「EC 102」のいずれかを取得する必要があるが、必ずしも両方を取得する必要はないとします。

追加要件:

また、EC001 を専攻する学生は、EC 200、EC 201、EC 202 の 3 つのコースをすべて受講する必要があります。

政治経済学 (EC002): 経済学と同様に、学生は「EC 101」または「EC 102」のいずれかを受験する必要がありますが、必ずしも両方を受験する必要はありません。また、EC002 を専攻する学生は、EC 200、EC 201、EC 202 の 3 つのコースのうち任意の 2 つを受講する必要があります。

コース

Course ID    Name
EC 101       Economics 101
EC 102       Economics 102
EC 200       Economics 200
EC 201       Economics 201
EC 202       Economics 202

メジャー

Major ID     Name
EC001        Economics
EC002        Political Economy

主な要件

MajorID      ReqID
EC001        R01
EC001        R02
EC002        R01
EC002        R03

要件

ReqID         ReqCount
R01           1
R02           3
R03           2

必須コースオプション

ReqID         CourseID
1             EC 101
1             EC 102
2             EC 200
2             EC 201
2             EC 202
3             EC 200
3             EC 201
3             EC 202

解釈

経済学を専攻する人 (EC001) は、専攻のすべての要件を満たす必要があります。つまり、MajorRequirements R01 および R02 を満たす必要があります。R01を満たすには、学生は利用可能なオプションから1つの必須コースを受講している必要があります。必要なコース オプションは EC 101 と EC 102 です。どちらかで十分でしょう。R02を満たすには、学生は利用可能なオプションから3つの必須コースを受講している必要があります。3 つのコース (EC 200、EC 201、EC 202) があるため、学生は 3 つすべてを受講する必要があります。

同様に、政治経済学 (EC002) を専攻する人は、その専攻のすべての要件を満たす必要があります。つまり、MajorRequirments R01 および R03 を満たす必要があります。以前と同様に、R01 を満たすには、学生は利用可能なオプション (EC 101 または EC 102) から 1 つの必須コースを受講している必要があります。R03を満たすには、学生は利用可能なオプションから2つの必須コースを受講している必要があります。3 つのコース (EC 200、EC 201、EC 202) があり、学生は 3 つのうち少なくとも 2 つを受講している必要があります。

明らかに、これを使用して、任意のセットから N 個の M 個のコースを要求できます。メジャー M が特定のコース C を必要とする場合、MajorRequirements テーブルには、ReqCount が 1 のメジャー M の ReqID R と、R および C を記録する RequiredCourseOptions が含まれます。 ReqID 値とそれぞれ 1 の ReqCount。ただし、R03 を使用した 3 つのコースのうち 2 つのコースの柔軟性を示したかったのです。対称性は、ReqCount 3 を使用した ReqID R02 の方がいくつかの点で優れていることを示唆しています。

卒業資格者の選抜

どのような学生が卒業する資格がありますか?

列 StudentID、Name、MajorID (および生年月日、入学日などの他の列) を持つ Student のテーブルと、列 StudentID および CourseID (および合格日と合格成績など) を持つ別のテーブル StudentPassedCourses を想定します。エントリは、学生がコースに合格した場合にのみ StudentPassedCourses に表示されます。

そして、卒業資格は、専攻の各要件を満たした者です。

TDQD — Test Driven Query Designを使用して、クエリを段階的に作成しましょう。

Q1:専攻の卒業要件数

SELECT MajorID, COUNT(ReqID) AS CountReqs
  FROM MajorRequirements
 GROUP BY MajorID

Q2: 学生による要件の合格数

SELECT s.StudentID, m.ReqID, COUNT(*) AS PassCount
  FROM StudentPassedCourses AS p
  JOIN Students             AS s ON p.StudentID = s.StudentID
  JOIN MajorRequirements    AS m ON s.MajorID = m.MajorID
 GROUP BY s.StudentID, m.ReqID

(これはかなり大きなステップです。別のステップに分割する必要があるかもしれません。)

Q3:一定の条件を満たす学生

これは、特定の ReqID の学生の合格数が少なくとも専攻で必要な合格数である学生と要件 ID をリストします。

SELECT p.StudentID, p.ReqID
  FROM (SELECT s.StudentID, m.ReqID, COUNT(*) AS PassCount  -- Q2
          FROM StudentPassedCourses AS p
          JOIN Students             AS s ON p.StudentID = s.StudentID
          JOIN MajorRequirements    AS m ON s.MajorID = m.MajorID
         GROUP BY s.StudentID, m.ReqID
       ) AS p
  JOIN MajorRequirements AS m ON p.ReqID = m.ReqID
 WHERE p.PassCount >= m.ReqCount

Q4: 各学生の要件数を集計する

SELECT r.StudentID, COUNT(*) AS ReqsPassed
  FROM (SELECT p.StudentID, p.ReqID  -- Q3
          FROM (SELECT s.StudentID, m.ReqID, COUNT(*) AS PassCount  -- Q2
                  FROM StudentPassedCourses AS p
                  JOIN Students             AS s ON p.StudentID = s.StudentID
                  JOIN MajorRequirements    AS m ON s.MajorID = m.MajorID
                 GROUP BY s.StudentID, m.ReqID
               ) AS p
          JOIN MajorRequirements AS m ON p.ReqID = m.ReqID
         WHERE p.PassCount >= m.ReqCount
       ) AS r
 GROUP BY r.StudentID

Q5:専攻に合格した学生

SELECT s.StudentID, s.Name, s.MajorID, m.Name Major
  FROM Students AS s
  JOIN Majors   AS m ON m.MajorID = s.MajorID
  JOIN (SELECT r.StudentID, COUNT(*) AS ReqsPassed  -- Q4
          FROM (SELECT p.StudentID, p.ReqID  -- Q3
                  FROM (SELECT s.StudentID, m.ReqID, COUNT(*) AS PassCount  -- Q2
                          FROM StudentPassedCourses AS p
                          JOIN Students             AS s ON p.StudentID = s.StudentID
                          JOIN MajorRequirements    AS m ON s.MajorID = m.MajorID
                         GROUP BY s.StudentID, m.ReqID
                       ) AS p
                  JOIN MajorRequirements AS m ON p.ReqID = m.ReqID
                 WHERE p.PassCount >= m.ReqCount
               ) AS r
         GROUP BY r.StudentID
       )        AS c ON c.StudentID = s.StudentID
  JOIN (SELECT MajorID, COUNT(ReqID) AS CountReqs    -- Q1
          FROM MajorRequirements
         GROUP BY MajorID
       )        AS r ON r.MajorID = s.MajorID
 WHERE c.ReqsPassed >= r.CountReqs

警告: テストされていない SQL!

于 2013-03-15T23:23:59.563 に答える