2017-02-28 72 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