你缺少一个表关联科目和学生(每点2):
// student [student_id] takes subject [subject_id]
takes(student_id,subject_id)
注意,每个基地台有关于应用情况的相关声明。使声明为真的行进入表中。请注意,表格定义看起来像是语句的简写。
// teacher [id] named [name] with email [email] teaches subject [subject_id]
teacher(id,name,email,subject_id)
// subject [id] named [name] is [description]
subject(id,name,description)
// student [id] named [name] lives at [location])
student(id,name,location)
// batch [id] at venue [venue] was taught by teacher [teacher_id] on date [date]
batch(id,venue,teacher_id,date)
// student-batch [id] reports student [student_id] being in batch [batch_id]
student-batch(id,student_id,batch_id)
CONSTRAINT ?? -- student [student_id] takes the subject that is taught by the teacher of batch [batch_id]
既然你看起来很难理解这个问题,我将根据我们如何推理表,约束和查询设计来推导它。
要在SQL中表达任何表,约束或查询,我们首先要确定它的语句。然后,我们可以将语句转换为简写。然后我们可以将简写转换为SQL。
一个表包含使其声明为真的行。所以我们通过在SQL中编写表名来获得满足基表语句的行。
通过在SQL中加入语句表,我们得到满足两个语句的AND的行。如果我们希望行满足条件的AND,那么我们在SQL中使用ON或WHERE。对于OR我们使用UNION。对于AND NOT,我们使用EXCEPT/MINUS(或LEFT JOIN成语)。
如果我们希望行满足某些列的某些值,即哪里存在某些列的值(但我们不想要该值),那么我们使用SELECT来删除SQL中的列。我们可以在我们的声明中使用FOR,重新列出我们保留的列。 FOR SOME或THERE所有列的存在都不能用SQL编写,但如果我们想知道是否有行满足语句,那么在SQL中,我们在语句的SELECT周围使用EXISTS作为条件。
// student [student_id] takes the subject that is taught by the teacher of batch [batch_id]
FOR SOME name, email, venue, date, takes.student_id, ... (
student [takes.student_id] takes subject [takes.subject_id]
AND teacher [teacher.id] named [name] with email [email] teaches subject [teacher.subject_id]
AND batch [batch.id] at venue [venue] was taught by teacher [batch.teacher_id] on date [date]
AND [takes.subject_id] = [teacher.subject_id]
AND [teacher.id] = [batch.teacher_id]
AND [student_id] = [takes.student_id]
AND [batch_id] = [batch.id])
简写:
// student [student_id] takes the subject that is taught by the teacher of batch [batch_id]
FOR SOME ... (
takes(takes.student_id,takes.subject_id)
AND teacher(teacher.id,name,email,teacher.subject_id)
AND batch(batch.id,venue,batch.teacher_id,date)
AND takes.subject_id = teacher.subject_id
AND teacher.id = batch.teacher_id
AND student_id = takes.student_id
AND batch_id = batch.id)
SQL:通过其表REPLACE语句,并通过JOIN或ON或WHERE,对于一些或者出现由SELECT存在,并且在那里想EXISTS:
// student [student_id] takes the subject that is taught by the teacher of batch [batch_id]
SELECT *
FROM takes JOIN teacher JOIN batch
WHERE takes.subject_id = teacher.subject_id
AND teacher.id = batch.teacher_id
AND student_id = takes.student_id
AND batch_id = batch.id
对于一个约束条件,我们想要一个条件(不是表格),没有满足该条件的行:
// whether THERE EXISTS student_id,batch_id (
student [student_id] takes the subject that is taught by the teacher of batch [batch_id])
EXISTS (...that SELECT...)
不幸的是,这不是一个约束,你可以很容易地检查在MySQL或大多数DBMS。
编辑:
,并需要得到的信息可以说一批的ID,老师的名字, 学生的某一天的名称。
现在我们正在编写一个查询。我们要行,其中:
FOR batch.id, teacher.name, student.name (
takes(takes.student_id,takes.subject_id)
AND teacher(teacher.id,teacher.name,email,teacher.subject_id)
AND batch(batch.id,venue,batch.teacher_id,date)
AND student(student.id,student.name,location)
AND student-batch(student-batch.id,student-batch.student_id,student-batch.batch_id)
AND takes.subject_id = teacher.subject_id
AND teacher.id = batch.teacher_id
AND student.id = takes.student_id
AND student-batch.student_id = takes.student_id
AND student-batch.batch_id = batch.id
AND @date = date)
这几乎就像除了FOR SOME实际上返回一些列的约束,添加一些其他的线,被点缀些暧昧的名字。 SQL就像直接翻译一样。请注意,现在我们必须加入student-batch,因为约束条件假设我们正在处理来自student-batch的行(id,student_id,batch_id)。
SELECT batch.id AS Batch, teacher.name AS Teacher, student.name AS Student
FROM takes JOIN teacher JOIN batch JOIN student JOIN student-batch
WHERE ... AND @date = date
你可以尝试的ON版本:
SELECT batch.id AS Batch, teacher.name AS Teacher, student.name AS Student
FROM takes
JOIN teacher ON takes.subject_id = teacher.subject_id
JOIN batch ON teacher.id = batch.teacher_id
JOIN ...
WHERE @date = date
什么是这方面的一个*批量*? –
批量就像实际的教学过程可以说在2014年8月1日的欧洲教师山姆教学,它就像一个教学活动。 – user1906399
看起来很近。你需要一个“老师主题”表格,而不是将主题放在教师记录中;一位教师可以教授多个科目。也可以从'batch'中删除'teacher_id'来代替使用'teacher-batch'表。 –