1

リレーショナル データベースには 3 つのテーブルがあります。SQL サーバーの使用。

person(id, type)
student(id, person_id, type, student specific fields)
teacher(id, person_id, type, teacher specific fields)

生徒と教師はどちらも人間であるため、生徒は教師と同様に、個人テーブルと生徒テーブルの両方にレコードを持ちます。学生と教師は個人への外部キーを持っています。学生と教師は異なるフィールド定義を持っているため、ユニオンは機能しません。

今、私はその人のIDを持っており、その人が学生か教師かによって、関連するテーブルから*を選択したいと思います(人ではありません)。

たとえば、その人が学生の場合、クエリで学生テーブルを選択したいと思います。

効率の悪い方法はいくつか思いつきますが、最適な方法を探しています。

4

3 に答える 3

2

ユニオンをお勧めします

 SELECT student.* 
 FROM student
 WHERE person_id= @id
 UNION
 SELECT teacher.* 
 FROM teacher
 WHERE person_id= @id
于 2012-10-03T13:03:43.137 に答える
1
if exists(select person_id from student where person_id = @id)
select * from student where person_id = @id
else
if exists(select person_id from teacher where person_id = @id)
select * from teacher where person_id = @id
于 2012-10-03T13:45:57.270 に答える
1

あなたの RDBMS がSQLServerである場合、podiluska の共用体に沿ってビューを抽象化し、Student と Teacher の特定のフィールドを共通の名前にマッピングし、マッピングが不可能な場合は NULL でパディングします。

また、生徒と教師が個人から継承すると仮定すると (つまり、どちらも個人に対して 0..1 対 1 である)、同じ主キーを共有できます。つまり、教師と生徒に新しい代理キーは必要ありません。

私はperson.type、その人が学生(S)か教師(T)かを決定すると仮定しました。

CREATE VIEW SubClassesOfPerson AS
   SELECT p.id as PersonId, 
          p.name as PersonName, 
          p.OtherBaseFieldsHere, 
          s.SomeStudentSpecificField AS MappedField1,
          s.SomeStudentSpecificFieldX AS MappedFieldX,
          s.SomeStudentSpecificField as MappedFieldForStudentOnly,
          NULL as MappedFieldForTeacherOnly -- Pad this because it can't be mapped
   FROM person p 
      INNER JOIN student s
      on s.person_id = p.id AND p.type = 'S'

   UNION

   SELECT p.id as PersonId, 
          p.name as PersonName, 
          p.OtherBaseFieldsHere, 
          t.SomeTeacherSpecificField AS MappedField1,
          t.SomeTeacherSpecificFieldX AS MappedFieldX,
          NULL as MappedFieldForStudentOnly,  -- Pad this because it can't be mapped
          t.SomeTeacherSpecificField as MappedFieldForTeacherOnly
   FROM person p 
      INNER JOIN teacher t
      on t.person_id = p.id AND p.type = 'T'
于 2012-10-03T13:46:25.943 に答える