2016-04-08 2 views
0

私はMicrosoft SQL Server 2014を使用しています。2つの外部キーからすべての可能な組み合わせを生成

私は3つのテーブルを持つ大学のデータベースを持っているとしましょう。 1つはコースのリスト、もう1つは年、もう1つはコースのリストです。

CREATE TABLE Courses (
    Course_ID varchar(5) PRIMARY KEY NOT NULL, 
    Name varchar(255) NOT NULL 
) 

CREATE TABLE Years (
    Year_ID tinyint 
) 

CREATE TABLE Coursework (
    CW_ID varchar(5) PRIMARY KEY NOT NULL, 
    Name varchar(255) NOT NULL, 
    Allowed varchar(255) NOT NULL 
) 

ここで、コースワークは、コース/年の任意の組み合わせに許可される可能性があります。だから、私はコースXの1年生に特別な学生、2年生と3年生のコースX、Y、Zの学生を許可するコースワークを持つことができます。もちろん1年と2年で、あるいはすべてのコースとすべての年を許可する1つです。

「許可」は、組み合わせが有効であることを確認します。多分、各テーブルの外部キー(コースと年)を参照することで確認できます。

しかし、どうすればいいですか?私は、複合主キーを使用して新しいテーブルを作成することを考えましたが、それは手動入力が必要となり、ペアの組み合わせに限定されます。

どうやら可能な組み合わせを生成し、それぞれの固有のプライマリキーを持つテーブルにリストし、それを「コースワーク」テーブルの外部キーとして参照する必要があります。しかし、私はちょっと立ち往生しています。任意のヒント?

EDIT:

私が欲しいものを明確にする:

は、以下のコーステーブルを想像してみて:

Course_ID Name 

A   Arithmetics 
B   Biology 
C   Chemistry 

そして次の年テーブル:

Year_ID 

1 
2 
3 

そして今、A教師は新しいコースワークを作成します。彼らは生物学や化学を学ぶ2年か3年で学生に利用したいと考えています。したがって、3年目に生物学を勉強している人、2年目に化学を勉強している人、1年目に生物学を勉強している人、または2年目にArithmeticsを勉強している人には利用できません。

教科書をテーブルに挿入します。

CW_ID Name    Allowed 

SA  Soil analysis B,C,2,3 

これは大丈夫だと思うが、どのように私は、彼らがそのようなコース/年が存在しないとして、例えば「X、5」を入力するからそれらを停止するために、存在する値を入力していることを確認してくださいでしょうか?

EDIT2:

私が何かをテストしていたが、それは間違いなく最良の解決策されていないほか、私もそれを実装する方法のわかりません。すべてのコース/年(trueまたはfalse)を1と0のすべての組み合わせで許可テーブルを移入することにより

CREATE TABLE YesOrNo (
    YesOrNo_ID bit PRIMARY KEY NOT NULL 
) 

CREATE TABLE Allowed (
    Allowed_ID int IDENTITY(1,1), 
    Arithmetics bit FOREIGN KEY REFERENCES YesOrNo(YesOrNo_ID) NOT NULL, 
    Biology bit FOREIGN KEY REFERENCES YesOrNo(YesOrNo_ID) NOT NULL, 
    Chemistry bit FOREIGN KEY REFERENCES YesOrNo(YesOrNo_ID) NOT NULL, 
    First bit FOREIGN KEY REFERENCES YesOrNo(YesOrNo_ID) NOT NULL, 
    Second bit FOREIGN KEY REFERENCES YesOrNo(YesOrNo_ID) NOT NULL, 
    Third bit FOREIGN KEY REFERENCES YesOrNo(YesOrNo_ID) NOT NULL 
) 

、教師はコースワークテーブルにAllowed_IDを挿入しなければならないでしょうし、それは次のようになりますどのコース/年が教室で許可されたかがわかっています。

しかし、手動ですべてのコースと年を属性として追加することは実用的ではなく、その場合でもすべての可能性を自動的にテーブルに設定する方法はわかりません。例から取る

、テーブルの行の1つは、次のようになります。コースワークテーブルの許可フィールドに

Allowed_ID Arithmetics Biology Chemistry First Second Third 

42   0    1   1   0  1   1 

と教師のと同じ入力「42」。

+0

私はあなたがしようとしているかを理解するのに苦労していますここで達成する。異なるテーブルのキー値に基づいて可能なすべての組み合わせのリストが必要な場合は、 'CROSS JOIN'でこれを行うことができます – mheptinstall

+0

なぜこれを具体化しますか?各テーブル内の少数の行でさえ、組み合わせの数が驚異的になります。あなたはここで本当に何をしようとしていますか?あなたがより良いアプローチを見つけるのを手助けすることができます。 –

+0

なぜGoogleは尋ねる前に? http://stackoverflow.com/questions/18716767/return-all-possible-combinations-of-values-in-columns-in-sql –

答えて

0

1つの列ではなく、多対多の結合表を使用して、どのコースがどのコースと年度に有効であるかを記録します。

CREATE TABLE ValidCourseworkByYear (
    VCWBY_ID int PRIMARY KEY IDENTITY(1,1), 
    CW_ID varchar(5) NOT NULL, 
    Course_ID varchar(5) NOT NULL, 
    Year_ID tinyint NOT NULL 
) 

これにより、データを複製したり、複数回使用することを防ぐことなく、作品、コース、年の間にリンクが作成されます。エントリーがそのテーブルに存在しない場合、その特定のワークコースと年度の組み合わせは無効です。

あなたのコーステーブルがすでにコースに外部キーが設定されている場合(つまり、1つのコースで1つの作業しか使用できないことを意味します)、このテーブルからCW_IDを削除できます。

また、文字列を主キーとして使用しないでください。彼らは貧弱に機能する。表示のために短い識別子が必要な場合は、それを別の列にして、ユニークな制約を入れます。あなたが行うことができ、ワンショット契約として

+0

どのようにそのテーブルに実際の情報を追加しますか?それは関係を正しく設定するだけですか? – Sanac

+0

はい、スキーマ定義は単に関係を定義します。結合テーブルを作成する正確な仕組みは、新しいデータを他のテーブルに挿入するか、既存のデータに対してこの関係を文書化するかによって異なります。それにもかかわらず、年、コース、および作業データを最初にそれぞれのテーブルに入れる必要があるため、結合テーブルに挿入する主キーがあります。これらの表にデータを設定し、選択した問合せを作成して適切な関係のキーを取得し、その結果を結合表に挿入できます。 –

0

、:

insert into Coursework (
    Course_ID , 
    Year_ID) 
select 
    Courses.Course_ID , 
    Years.YearID 
from 
    Courses 
cross join 
    Years 

そして、あなたは重複を追加しない&空想を取得したい場合:

insert into Coursework (
    Course_ID , 
    Year_ID) 
select 
    Courses.Course_ID , 
    Years.Year_ID 
from 
    Courses 
cross join 
    Years 
left join 
    Coursework 
on 
    Courses.Course_ID = Coursework.Course_ID 
and 
    Years.Year_ID = Coursework.Year_ID 
where 
    Courses.CW_ID is null 
+0

「無効な列名 'Course_ID'」と表示されます。私はそれをSQLFiddleに貼り付けます – Sanac

+0

心配しないで、Course_IDとYear_IDをCourseworkテーブルの属性として追加する必要がありました...しかし、まだ問題は解決していません。最初に、コースワークにはすでにCW_IDと名前が設定されていますが、これは無視されます。しかし、私はこのすべてを(たとえばValidCourseworkByYearのような)別のテーブルに入れても、コースワークがすべてのコースや年間を通して利用可能であると述べるにはどうすればよいでしょうか?またはコースXの1年目と2年目、または何か他のもの。それはちょうどコース/年(X、1)(X、2)(X、3)(Y、1)(Y、2)(Y、3) X、Y、1,2) – Sanac

関連する問題