הבלוג של גרי רשף

31/08/2010

מציאת התאמות לפי קריטריונים גמישים

Filed under: Uncategorized — תגיות: , , , , — גרי רשף @ 09:21

בפורום בסיסי נתונים שבתפוז הופיעה שאלה לגבי התאמת מועמדים למכללות:
יש מועמדים כשלגבי כל אחד יש נתונים אם שירת בצבא, יש לו בגרות, עשה  יח"ל במתימטיקה וכו';
ויש מכללות שתנאי הקבלה שלהן יכולים לכלול חלק מהסעיפים הנ"ל;
ויש למצוא איזה מועמד מתאים לאיזו מכללה.

הפתרון הראשון שעלה בדעתי הוא לצרף לטבלת המועמדים עמודות כן/לא בהתאם לתנאים,
לצרף לטבלת המכללות עמודות כן/לא בהתאם,
ולשלוף כך:

Select  *

From    Students S

Inner Join Universities U

        On S.Army>=U.Army

        And S.Bagrut>=U.Bagrut

        And S.Math5>=U.Math5;

Go

הבעייה בפתרון הוא היעדר גמישות: בכל פעם שמתווסף קריטריון חדש – יש להוסיף עמודה לטבלת הסטודנטים, עמודה לטבלת המכללות, ולשנות את השליפה נ"ל ולהוסיף לה תנאי; ובנוסף- לא כל הקריטריונים הם מסוג של כן/לא ויש קריטיונים כמותיים כמו ציון ממוצע בבגרות, וגם בהם יש לטפל.

זו כמובן בעייה מורכבת יותר, והנה הפתרון המסודר עבורה.

קודם כל נוודא שכל האובייקטים שאני הולך ליצור אינם קיימים (בדרך כלל אני מבצע את הבדיקה בסמוך ליצירת האובייקט, אבל כשיש תלויות בין אובייקטים – המחיקה שלהם צריכה להתבצע בסדר הפוך ליצירה):

Use tempdb;

Go


If Object_Id('Students_Criteria') Is Not Null Drop Table Students_Criteria;

Go


If Object_Id('Students') Is Not Null Drop Table Students;

Go


If Object_Id('Universities_Criteria') Is Not Null Drop Table Universities_Criteria;

Go


If Object_Id('Universities') Is Not Null Drop Table Universities;

Go


If Object_Id('Criteria') Is Not Null Drop Table Criteria;

Go

כעת ניצור בנפרד טבלת סטודנטים, טבלת מכללות, וטבלת קריטריונים (עדיין איננו קובעים מה הקריטריונים לכל מכללה ומה סגולותיו של כל מועמד, אלא מגדירים קריטריונים לשימוש בהמשך באופן מסודר), ולכל טבלה נזין נתונים:

Create Table Students(Name Varchar(50) Primary Key);

Go


Insert Into Students

Select 'Avi'

Union All

Select 'Batya'

Union All

Select 'Gila'

Union All

Select 'Dana';

Go


Create Table Criteria(Name Varchar(50) Primary Key);

Go


Insert Into Criteria

Select 'Psichometric'

Union All

Select 'Memuza Bagrut'

Union All

Select 'Army'

Union All

Select 'Math 5';

Go


Create Table Universities(Name Varchar(50) Primary Key);

Go


Insert Into Universities

Select 'Bar Nitzan'

Union All

Select 'Haminhala'

Union All

Select 'Hamercaz';

Go

כעת ניצור טבלאות סטודנטים-קריטריונים (טבלת ביניים עבור יחס N:N בין הסטודנטים לקריטריונים),

וטבלת מכללות-קריטריונים (יחס N:N בין המכללות לקריטריונים),

ונזין לתוכן נתונים:

Create Table Students_Criteria(Student Varchar(50) Foreign Key References Students(Name),

                                                        Criteria Varchar(50) Foreign Key References Criteria(Name),

                                                        Score SmallInt,

                                                        Constraint PK_Students_Criteria Primary Key(Student,Criteria));

Go



Insert Into Students_Criteria

Select 'Avi','Psichometric',500

Union All

Select 'Avi','Army',1

Union All

Select 'Batya','Memuza Bagrut',70

Union All

Select 'Batya','Psichometric',700

Union All

Select 'Gila','Math 5',1

Union All

Select 'Gila','Army',1;

Go


Create Table Universities_Criteria(University Varchar(50) Foreign Key References Universities(Name),

                                                        Criteria Varchar(50) Foreign Key References Criteria(Name),

                                                        Score SmallInt,

                                                        Constraint PK_Universities_Criteria Primary Key(University,Criteria));

Go


Insert Into Universities_Criteria

Select 'Bar Nitzan','Psichometric',550

Union All

Select 'Bar Nitzan','Army',1

Union All

Select 'Haminhala','Psichometric',400;

Go

כדאי לשים לב שכשיוצרים Foreign Key – הטבלה שבצד הרבים צריכה לכלול הפניה לכל עמודות המפתח בטבלה שבצד ה-1,

וכשמדובר ביחס של רבים לרבים – יש לפנות לעמודות המפתח בשתי הטבלאות, והמפתח בטבלת הביניים יכלול את כל עמודות ה-Foreign Key לפחות (במקרה שלנו המודל פשוט- עמודת מפתח בכל אחת מהטבלאות שבצד ה-1, ושתי עמודות ה-Foreign Key בטבלאות הביניים הן המפתח שלהן).

וכעת לשליפה: יש לשלוף את כל ההתאמות בין סטודנטים למכללות

שעבורן לא קיים קריטריון של המכללות

שעבורו לא קיים קריטריון הולם (=שעומד בזה של המכללות) של הסטודנטים:

Select        M.Name,

                S.Name

From        Universities M,

                Students S

Where        Not Exists (Select        *

                                        From        Universities_Criteria M1

                                        Where        M1.University=M.Name

                                                        And Not Exists (Select        *

                                                                                From        Students_Criteria S1

                                                                                Where        S1.Student=S.Name

                                                                                                And S1.Criteria=M1.Criteria

                                                                                                And S1.Score>=M1.Score));

Go

קצת קשה להבין את הלוגיקה ולצלוח את השימוש ב-Exists..

בכל מקרה- ניתן לראות שכל הסטודנטים יכולים להתקבל למכללת "המרכז" מכיוון שאין לה אף קריטריון לקבלה, כולל דנה שאין לה אף יכולת..

מודעות פרסומת

להגיב »

עדיין אין תגובות.

RSS feed for comments on this post. TrackBack URI

להשאיר תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s

בלוג בוורדפרס.קום.

%d בלוגרים אהבו את זה: