2017-02-28 75 views
3

我正在制作一个系统,使用SQL Server Management Studio显示学生时间表并将其链接到一个Visual Studio程序(这与我的问题无关,但只是增加了上下文),但是我有一个专业此刻我的数据库表出现问题,我需要一些帮助。SQL数据库学生时间表系统

我的项目的基本背景是有3个表格,Lesson,StudentSubject。这些表格填充了小的测试样本数据集。

Lesson表:

LessonID DayOfWk PeriodValue SubjectID Room blockLessonIsIn 
------------------------------------------------------------------- 
1   Mon  2   1   G8  2 
2   Mon  3   1   G8  2 
3   Mon  4   1   G8  2 
4   Mon  5   2   N5  1 
5   Tue  1   3   SF5  4 
6   Tue  3   2   N7  1 
7   Wed  1   3   SF5  4 
8   Wed  2   1   H9B  2 
9   Wed  5   1   G8  2 
10   Thu  1   3   SF4  4 
11   Thu  3   2   N7  1 
12   Thu  5   3   SF5  4 
13   Fri  1   3   SF5  4 
14   Fri  2   1   G8  2 
15   Fri  3   1   H9B  2 
16   Fri  4   2   SP2  1 
17   Mon  1   5   H1  1 
18   Tue  5   5   H1  1 
19   Thu  3   5   H1  1 
20   Fri  4   5   H1  1 
21   Wed  4   4   S1  3 
22   Fri  5   4   S1  3 
23   Tue  1   2   N1  4 
24   Tue  2   2   N1  4 
25   Wed  1   2   N1  4 
26   Thu  1   2   N1  4 
27   Thu  4   2   N1  4 

Subject表:

SubjectID Title 
--------------------------------- 
1   Computing 
2   Maths 
3   Economics 
4   Physics 
5   Geography 

Student表:

UserID Forname Surname  SchlYear InOrOut Block1 Block2 Block3 Block4 Pword 
---------------------------------------------------------------------------------- 

1  Jake Richardson 13   1  2  1  NULL 3  password 
2  Russell Penn  13   1  5  1  NULL 2  russpass 
3  Xander Sheppard 13   1  2  1  4  NULL xander 
4  Dan  Bostock  13   1  2  1  4  NULL pass 

这些表通过以下彼此连接:

  • Lesson表 - 经由SubjectID>Subject表作为外键
  • Subject表 - 经由Block1>Student表,Block2Block3Block4SubjectID如在每一个外键,具有与对象的每个块,其给每个学生最多4个可能的主题

我的目的是查询表,以便查询运行一天和周期值时可以找到一个奇异值与个人进入,从而找到个人在那一天和那段时间的教训。

查询我目前是如下,如果试图寻找例如杰克·理查森的课周二期1:

SELECT 
    lesson.SubjectID 
FROM 
    lesson_tbl AS lesson 
LEFT OUTER JOIN 
    student_tbl AS subject1 ON lesson.SubjectID = subject1.Block1 
LEFT OUTER JOIN 
    student_tbl AS subject2 ON lesson.SubjectID = subject2.Block2 
LEFT OUTER JOIN 
    student_tbl AS subject3 ON lesson.SubjectID = subject3.Block3 
LEFT OUTER JOIN 
    student_tbl AS subject4 ON lesson.SubjectID = subject4.Block4 
WHERE 
    lesson.DayOfWk = 'Mon' 
    AND lesson.PeriodValue = '5' 
    AND ((subject1.UserID = '1' AND lesson.blockLessonIsIn = '1') OR 
     (subject2.UserID = '1' AND lesson.blockLessonIsIn = '2') OR 
     (subject3.UserID = '1' AND lesson.blockLessonIsIn = '3') OR 
     (subject4.UserID = '1' AND lesson.blockLessonIsIn = '4')); 

,这将成功返回值2,即数学。

然而,例如,如果我们要寻找拉塞尔·潘的价值在周二期间1:

SELECT 
    lesson.SubjectID 
FROM 
    lesson_tbl AS lesson 
LEFT OUTER JOIN 
    student_tbl AS subject1 ON lesson.SubjectID = subject1.Block1 
LEFT OUTER JOIN 
    student_tbl AS subject2 ON lesson.SubjectID = subject2.Block2 
LEFT OUTER JOIN 
    student_tbl AS subject3 ON lesson.SubjectID = subject3.Block3 
LEFT OUTER JOIN 
    student_tbl AS subject4 ON lesson.SubjectID = subject4.Block4 
WHERE 
    lesson.DayOfWk = 'Tue' 
    AND lesson.PeriodValue = '1' 
    AND ((subject1.UserID = '2' AND lesson.blockLessonIsIn = '1') OR 
     (subject2.UserID = '2' AND lesson.blockLessonIsIn = '2') OR 
     (subject3.UserID = '2' AND lesson.blockLessonIsIn = '3') OR 
     (subject4.UserID = '2' AND lesson.blockLessonIsIn = '4')); 

则返回值的数学2个,即3个值3倍的值,而应该只返回1数学的价值,因为在我已经添加的阻塞约束内,在星期二的周一只有1个数学值。

我知道数学已经跨越了第一块和第四块,但这是主意,而blockLessonIsIn旨在弥补这样一个事实,即它应该只选择与数学中特定块相关的课程

我的数据库设计有什么严重错误,还是我愚蠢地错过了一个明显的错误。数据库将被塑造到我的程序中,该程序已经被创建用于传递DayOfWk和PeriodValue等值,所以这只是阻止我回归的唯一的东西,但它让我完全难以理解3个数值的选择位置。

请注意,时间表不需要列,所以如果他们没有被引用(即课堂表中的房间)忽略它们。

如果您对我的程序或任何可能忘记提及的问题有任何疑问,或者需要我更详细地了解我正在尝试使用某些代码行实现的内容,请不要问,因为这是我的计划中的主要绊脚石。

感谢您的任何帮助或许能够提供!

+0

这也可能是值得我提的是,除去LEFT OUTER JOIN student_tbl AS subject1 ON lesson.SubjectID = subject1.Block1在我的错误代码做INFACT导致正确的结果进行打印。 – Jayzaaa

+2

你真的需要阅读规范化。你不应该有Block1,Block2等......这些应该是另一个表中的行。 –

+0

我知道的任何想象都不是最有效的方法,但它可以做到吗?之前我已经开始工作了,但是在加入数学模块4的数学课后,这个问题就诞生了。如果不能解决这个问题,你有没有什么建议可以用来使它更加高效? – Jayzaaa

回答

1

我认为您的课程表中可能有一些数据损坏。在阅读你的问题和你想要做的事情之后,我认为在课程中每个(日,周期)对都应该是唯一的。例如,如果一个学生在星期三的第一周,那么我们应该可以肯定地说他在数学。但是,这似乎并非如此。如果我们运行下面的查询,

select dayofwk, periodValue, COUNT(*) 
    from lesson_tbl 
    group by dayofwk, periodValue 
    having COUNT(*) > 1 

我们得到下面的结果

+ ------- + ----------- + ----- + 
| dayofwk | periodValue | count | 
+ ------- + ----------- + ----- + 
| thu  | 1   | 2  | 
| tue  | 1   | 2  | 
| wed  | 1   | 2  | 
| thu  | 3   | 2  | 
| fri  | 4   | 2  | 
+ ------- + ----------- + ----- + 

这告诉我们,这些(天,期间)的组合不是唯一的。如果学生在星期三的第一周,那么我们无法确定他是否在Math或Econ。

什么从这里做

(1)如果你不相信,(天,期间)的组合应在课表独特的,那么你想要什么是不可能的。您无法找到(用户,日期,时间段)的“单数值”。 (2)如果您认为(课程,时间段)组合在课程表中必须是唯一的,则修复损坏的数据。然后建立以下查询

declare @dayQuery varchar(3) = 'tue' 
declare @PeriodQuery int = 1 
declare @userQuery int = 1 

select * 
    from lesson_tbl L 
    inner join student_tbl U 
     on case L.blockLessonIsIn when 1 then U.Block1 
            when 2 then U.Block2 
            when 3 then U.Block3 
            when 4 then U.Block4 
      end = L.subjectID 
    where L.dayofwk = @dayQuery 
     and L.periodValue = @PeriodQuery 
     and U.userID = @userQuery 
+0

谢谢!这有效地解决了我当前数据库中的问题,但是我一定会尝试对表格进行规范化处理,以便在有时间的情况下进行缓解。 – Jayzaaa