2017-02-28 12 views
3

私は、SQL Server Management Studioを使用して学生タイムテーブルを表示し、それをVisual Studioプログラムにリンクするシステムを作成しています(問題は無関係ですが、コンテキストを追加するだけです)。私のデータベーステーブルを現時点で発行しており、私はいくつかの助けが必要です。SQLデータベース学生タイムテーブルシステム

私のプロジェクトの基本的な背景は、Lesson,StudentおよびSubjectという3つのテーブルがあるということです。テーブルには小さなテストサンプルデータセットが入力されます。

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テーブル - 外部キー
  • SubjectテーブルとしてSubjectIDを介し>Subjectテーブル - それぞれの外部キーとしてSubjectIDを持つ>StudentBlock1介しテーブル、Block2Block3Block4、被験者に関連する各ブロックとその各生徒に最大4つの可能な科目を与えます

私の目的は、1日の値が1日と期間の値に対して実行されたときに1つの特異値が見つかるようにテーブルを照会することです個人はuserIDと入力され、その日および期間に個人が持っているレッスンが見つかります。

次のように火曜日期間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にラッセル・ペンの値を検索した場合:それだけ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つの数学値しかないので、数学の価値があります。

ブロック1とブロック4の両方で数学が交差することは知っていますが、これが理念です.blockLessonIsInは、数学が属する特定のブロックに関連するレッスンのみを選択する必要があるという事実を是正することを目的としています

私のデータベース設計には重大な問題がありますか、それとも私がばかげて逃したような目障りなエラーですか。データベースは、DayOfWkやPeriodValueなどの値を渡すために既に作成されたプログラムに組み込まれていますので、これは私を後押ししている唯一のものですが、数学の3つの値が選択されている場所はまったく分かりません。

時刻表には不要な列があるので、引用されていない場合(つまり、レッスンテーブルのルーム)には無視してください。

私のプログラムや、私が言及したことを忘れているかもしれないこと、または私が特定のコード行で達成しようとしていることについてもっと詳しく調べる必要があるものについて質問がある場合は、私のプログラムの主要な障害です。

ご協力いただきありがとうございます。

+0

を構築します。 – Jayzaaa

+2

正規化を読む必要があります。あなたはBlock1、Block2等を持ってはいけません。それらは別のテーブルの行でなければなりません。 –

+0

それは私が知っている想像力のあらゆるストレッチで最も効率的な方法ではありませんが、それは可能ですか?私は前に働いていましたが、数学のブロック4から数学のレッスンを追加すると、この問題が生まれました。これが修正できない場合は、正規化を使用して効率化するために使用できる提案はありますか? – Jayzaaa

答えて

1

レッスンテーブルにのデータが破損している可能性があります。あなたの質問を読んだ後、できることをしたいと思ったら、レッスンの各(日、時)のペアがユニークであるべきだと思うのは妥当なようです。たとえば、学生が水曜日の期間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  | 
+ ------- + ----------- + ----- + 

を取得するには、一意ではありません。学生が水曜日の期間1にいる場合、私たちは彼が数学か経済学であるかを判断できません。

ここから何をすべきか

(1)あなたは(日、期間)の組み合わせは、授業のテーブル内で一意であることを信じていない場合、あなたが望むものは不可能です。 a(ユーザー、日、期間)に「1つの特異値」を見つけることはできません。

(2)レッスンテーブルで(日、期間)の組み合わせが一意でなければならないと思われる場合は、破損したデータを修正してください。そして、また、私はLEFT OUTERが私の障害のあるコードにsubject1 ON lesson.SubjectID = subject1.Block1 AS student_tblのJOIN削除すると印刷されている正しい結果にInfactはリードをしていることは注目に値するかもしれない次のクエリ

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

関連する問題