2016-04-08 70 views
0

我正在使用Microsoft SQL Server 2014.從2個外鍵生成所有可能的組合

假設我有一個有3個表的大學數據庫。一個列出課程,一個課程,以及一門課程。

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專業的一年級學生專門學習,另一門課程允許學生參加2年級和3年級的X,Y和Z課程,其中一門課程允許所有年級的課程X的學生,一門允許學生在第一年和第二年無論如何,甚至是允許所有課程和所有年份的課程。 (我希望這能讓我的觀點得以實現。)

「允許」將通過引用每個表(課程和年)的外鍵來驗證組合是否有效。

但我該怎麼做?我想過使用複合主鍵創建一個新表,但這需要手動輸入,並且它將被限制在成對的組合中。

所以我的猜測是我需要以某種方式生成可能的組合,將它們列在一個表中,每個主鍵都有一個唯一的主鍵,並將其作爲「課程作業」表中的外鍵引用。但是,我有點卡住了。有小費嗎?

編輯:

爲了澄清我想:

想象一下以下的課程表:

Course_ID Name 

A   Arithmetics 
B   Biology 
C   Chemistry 

而且隨後的幾年表:

Year_ID 

1 
2 
3 

而現在,一個老師創建一門新課程。他們希望在2或3年級的時候向學生提供,學習生物學或化學。因此,第3年有人會學習生物學,第2年學習化學,但不適合第1年學習生物學的人或第2年學習算術的人。

他們會將課程作業插入表中。

CW_ID Name    Allowed 

SA  Soil analysis B,C,2,3 

這將是罰款,但我怎麼會檢查它們正在進入存在的價值,進入「X 5」,例如阻止他們,因爲這些當然/年不存在?

EDIT2:

我測試的東西,但除了它絕對不是最好的解決辦法,我什至不知道如何實現它。

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 
) 

通過與所有的課程/年的1和0(true或false)的所有組合填充允許表中,老師將只需要插入Allowed_ID在習作表,那麼這將是已知哪門課程/年課程被允許。

但是,手動添加所有課程和年份作爲屬性是不切實際的,即使如此,我也不知道如何自動填充所有可能性。

從例如以中,表中的行之一是這樣的:

Allowed_ID Arithmetics Biology Chemistry First Second Third 

42   0    1   1   0  1   1 

而且老師剛輸入「42」到在習作表允許的領域。

+0

我竭力要了解你們什麼在這裏實現。如果你想要的是基於來自不同表格的鍵值的所有可能組合的列表,那麼你可以用'CROSS JOIN'來做到這一點。 – mheptinstall

+0

爲什麼你想實現這個?即使在每個表格中有少量的行,這些組合的數量也是驚人的。你真正想在這裏做什麼,我們可以幫助你找到更好的方法。 –

+0

爲什麼你之前沒問過谷歌? http://stackoverflow.com/questions/18716767/return-all-possible-combinations-of-values-in-columns-in-sql –

回答

0

您想要一個多對多的連接表,而不是單個列來記錄哪些作品對於哪些課程和年份有效。

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 
) 

這會在工作片斷,課程和年份之間創建鏈接,而不會複製數據或防止其被多次使用。如果該條目不存在於該表格中,則該特定的工作 - 課程年度組合是無效的。

如果你的課程表已經是外部鍵入課程(這意味着一項工作只能在一門課程中使用),那麼你可以從這個表中刪除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作爲屬性添加到課程表中......但仍然不能解決問題。首先,課程作業已經填入了CW_ID和姓名,這將忽略這一點。但即使我把所有這些都放到了一個單獨的表格中(比如ValidCourseworkByYear),我怎樣才能說明課程作業可用於所有課程和所有年份?或者X或者其他任何課程的第一年和第二年。(X,2)(X,3)(Y,1)(Y,2)(Y,3)等的組合,但不是像( X,Y,1,2) – Sanac

相關問題