1

在关系数据库中,我有三个表。使用 SQL Server。

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

学生和老师都是人,因此学生和老师都会在个人和学生表中都有记录。学生和老师对人有外键。学生和老师有不同的领域定义,因此联合将不起作用。

现在我有了这个人的 id,根据这个人是学生还是老师,我想从相关表(不是人)中选择 *。

例如,如果此人是学生,我希望我的查询选择学生表。

我可以想到一些低效的方法,但我正在寻找最佳的方法。

4

3 回答 3

2

我建议一个 UNION

 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 回答