2012-10-03 70 views
1

在關係數據庫中,我有三個表。使用SQL Server。通過一般關係選擇表的

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

學生和老師都是人,所以學生在老師和學生表中都會有記錄。學生和老師都有外鍵給人。學生和老師有不同的字段定義,因此工會不起作用。

現在我有該人的身份證,並根據該人是否是學生或教師我想從相關表格(不是人)中選擇*。

例如,如果該人是學生,我希望我的查詢選擇學生表。

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

+0

你想返回哪些列?如果不知道這種查詢,就無法正確構建。 – RBarryYoung

+0

如果學生和教師'是'人(即繼承人),那麼你可能不需要一個新的代理鍵 - 他們可以繼續使用'person(id)'鍵 – StuartLC

+1

你還沒有指出你的數據庫系統,重複使用,但在標準SQL中,任何特定的查詢只會引用特定的表,並且結果集的「形狀」(即列,特別是每列的名稱和類型)是固定的。 –

回答

2

我會建議一個UNION

SELECT student.* 
FROM student 
WHERE person_id= @id 
UNION 
SELECT teacher.* 
FROM teacher 
WHERE person_id= @id 
+0

僅當學生和教師表具有相同的列定義 – RBarryYoung

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 
+0

KISS的完美示例時纔有效。 – Luftwaffe

+0

未來我會在原則和地區經理這樣的系統中擁有更多的人。你認爲這種方法有多高效? –

1

如果您的RDBMS是SQLServer,那我就抽象沿podiluska聯盟的線條,映射出在學生和教師共同的名字具體領域的視圖,並填充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'