הפרוייקט הזה נכתב בשותפות עם גילת ר. ושלמה ב.
מטעמי פרטיות שמותיהם המלאים לא מפורסמים ברבים.
במסגרת הלימודים לתואר שני, נתבקשנו לייצר פרוייקט SQL לפי דאטהסט שאותו אנחנו בוחרים.
בזכות ההצלחה הגדולה של נבחרת ישראל באולימפיאדה החלטנו להעמיק את הידע שלנו ב-SQL באמצעות חקירת דאטהסט הקשור למנצחי האולימפיאדה הנוכחית.

רגע לפני שמתחילים 🙋

השתמשנו בדאטהסט מהמם מאתר Kaggle- תוכלו לצפות בו בקישור הזה.
לאחר שהורדנו את הדאטהסט השמטנו ממנו רשומות שהיו לא רלוונטיות (כמו תחביבים, מקום לידה, שם האבא וכו’) - בכדי ליעל את גודל המסד ולדאוג ששליפות יהיו מהירות יותר.
כמו כן נרמלנו את שלושת הטבלאות כך שלא יהיו נתונים שחוזרים על עצמם פרט לקוד הספורטאי שאותו בחרנו בתור Primary Key.

על מנת להכניס את הדאטהסט הזה לתוך מסד הנתונים שלנו נעזרנו בכלי Convert CSV to SQL שפשוט הציל אותנו משעות של עבודה מאתגרת.

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

לפני שניתן יהיה להריץ את הסקריפט, ומכיוון שהוא נחשב כבד ומבצע לא מעט איטרציות על מסד הנתונים, יש לאפשר ל-MySQL Workbench לבצע Queries באורך של יותר מ-30 שניות.
על מנת לעשות זאת יש להיכנס ל:

Edit –> Preferences –> SQL Editor

ושם לשנות בשדה DBMS Connection Read Timeout Interval את הערך ל- 600 שניות ולא 30 כפי שמופיע כברירת מחדל.

ERD -Olympics 2024


לפני שנצלול לשאילתות ולמחקר שאנחנו רוצים לבצע על מסד הנתונים, ניגש תחילה לתרשים ה-ERD:
ERD (Entity-Relationship Diagram) הוא כלי חיוני לא רק בתכנון מסדי נתונים אלא גם בחקירתם. כאשר אנו בוחנים מסד נתונים קיים, ERD מספק לנו תצוגה גרפית וברורה של המבנה שלו, הקשרים בין הישויות השונות והאופן שבו הנתונים מאורגנים.
תרשים ה-ERD של המסד שלנו נראה כך (לחצו על התמונה להגדלה): ERD -Olympics 2024

חקירה, שאילתות ומה שבניהם 🔬

על מנת להעשיר את הפלט בחרנו להשתמש בסגנונות כתיבת שאילתות רבים.

1. שאילתה מסוג JOIN

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

SELECT 
    a.country AS Country,
    cp.Population2024 AS Population,
    COUNT(DISTINCT m.code) AS Num_Medallists,
    (COUNT(DISTINCT m.code) / cp.Population2024) * 1000000 AS Medallists_Per_Million
FROM  medallists m
JOIN  athletes a ON m.code = a.code
JOIN  country_population cp ON a.country = cp.Country
GROUP BY  a.country, cp.Population2024
ORDER BY  Medallists_Per_Million DESC;

תוצאותיה:

Country Population Num of Medallists Medallists Per Million
Grenada 126887 2 15.7620
Fiji 943072 14 14.8450
Dominica 73368 1 13.6290
New Zealand 5269939 45 8.5380
Netherlands 17671125 107 6.0550
Saint Lucia 180805 1 5.5300
Denmark 5939695 26 4.3770
Norway 5514477 23 4.1700
Australia 26699482 81 3.0330
Lithuania 2692798 7 2.5990
France 64881830 157 2.4190
Serbia 7097028 16 2.2540
Botswana 2719694 6 2.2060
Hungary 9994993 22 2.2010
Jamaica 2824738 6 2.1240
Bahrain 1498712 3 2.0010
Croatia 3986627 7 1.7550
Georgia 3717425 6 1.6140
Ireland 5089478 8 1.5710
Armenia 2777979 4 1.4390
Slovenia 2118965 3 1.4150
Spain 47473373 64 1.3480
Sweden 10673669 14 1.3110
Canada 39107046 51 1.3040
Switzerland 8851431 10 1.1290
Germany 83252474 89 1.0690
Italy 58697744 60 1.0220
Greece 10302720 10 0.9700
Bulgaria 6618615 6 0.9060
Kyrgyzstan 6839606 6 0.8770
Cyprus 1268467 1 0.7880
Romania 19618996 15 0.7640
Cuba 11174587 8 0.7150
Poland 40221726 27 0.6710
Austria 8977139 6 0.6680
United States 341814420 226 0.6610
Israel 9311652 6 0.6440
Belgium 11715774 7 0.5970
Azerbaijan 10462904 6 0.5730
Japan 122631432 68 0.5540
Morocco 38211459 20 0.5230
Argentina 46057866 19 0.4120
Kazakhstan 19828165 8 0.4030
Portugal 10223349 4 0.3910
Qatar 2737061 1 0.3650
Uzbekistan 35673804 13 0.3640
Albania 2826020 1 0.3530
South Africa 61020221 21 0.3440
Ukraine 37937821 13 0.3420
Puerto Rico 3268802 1 0.3050
Tajikistan 10331513 3 0.2900
Mongolia 3493629 1 0.2860
Brazil 217637297 61 0.2800
Ecuador 18377367 5 0.2720
Dominican Republic 11434005 3 0.2620
Tunisia 12564689 3 0.2380
Panama 4527961 1 0.2200
Slovakia 5702832 1 0.1750
Singapore 6052709 1 0.1650
Kenya 56203030 8 0.1420
Guatemala 18358430 2 0.1080
Chile 19658839 2 0.1010
Jordan 11384922 1 0.0870
Malaysia 34671895 3 0.0860
China 1425178782 121 0.0840
Thailand 71885799 6 0.0830
Algeria 46278751 3 0.0640
Colombia 52340774 3 0.0570
Mexico 129388467 7 0.0540
Zambia 21134695 1 0.0470
Uganda 49924252 2 0.0400
Peru 34683444 1 0.0280
Egypt 114484252 3 0.0260
Philippines 119106224 3 0.0250
Ethiopia 129719719 3 0.0230
India 1441719852 21 0.0140
Indonesia 279798049 2 0.0070
Pakistan 245209815 1 0.0040

התובנות והמענה על שאלת המחקר: התוצאות מאוד מפתיעות. בעוד שהיינו מצפים שארה"ב תהיה אלופת המדד- דווקא מדינות שפחות ציפינו מהם מככבות בראש הרשימה.
דבר שיכול להוות כר פורה למחקר עתידי.

2. שאילתה מסוג Subquery

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

SELECT 
    m.discipline AS Discipline,
    AVG(TIMESTAMPDIFF(YEAR, a.birth_date, m.medal_date)) AS Avg_Age_Medallists,
    (
        SELECT 
            AVG(TIMESTAMPDIFF(YEAR, a2.birth_date, CURDATE()))
        FROM 
            teams t2
        JOIN 
            team_athletes ta ON t2.code = ta.team_code
        JOIN 
            athletes a2 ON ta.athlete_code = a2.code
        WHERE 
            t2.discipline = m.discipline
    ) AS Avg_Age_Team_Members
FROM 
    medallists m
JOIN 
    athletes a ON a.code = m.code
WHERE 
    INSTR(a.disciplines, m.discipline) > 0
GROUP BY 
    m.discipline
ORDER BY 
    Avg_Age_Medallists DESC;

תוצאותיה:

Discipline Avg_Age_Medallists Avg_Age_Team_Members
Equestrian 38.6818 39.3776
Volleyball 30.1923 28.0064
3x3 Basketball 29.5833 29.6563
Handball 29.4681 28.5632
Sailing 28.9762 28.9103
Golf 28.8333
Basketball 28.7222 27.8646
Cycling Road 28.6667
Fencing 28.2111 27.2813
Cycling Mountain Bike 28.0000
Triathlon 27.9444 28.1875
Rowing 27.8750 27.4638
Beach Volleyball 27.6667 29.4063
Cycling BMX Racing 27.6667
Tennis 27.5417 29.7030
Canoe Sprint 27.3889 27.2511
Canoe Slalom 27.1111
Boxing 27.0962
Judo 26.7238 26.6354
Hockey 26.7157 26.9470
Shooting 26.6852 26.4231
Wrestling 26.5333
Rugby Sevens 26.5256 26.3470
Cycling Track 26.3590 26.4221
Surfing 26.3333
Water Polo 26.3077 26.8881
Athletics 26.0737 25.6569
Modern Pentathlon 26.0000
Badminton 25.7826 27.0204
Breaking 25.5000
Marathon Swimming 25.3333
Archery 25.3333 24.6172
Cycling BMX Freestyle 25.1667
Weightlifting 24.9259
Table Tennis 24.6000 27.0313
Football 24.5645 24.0980
Sport Climbing 23.8333
Trampoline Gymnastics 23.6667
Artistic Gymnastics 23.4776 23.1765
Swimming 23.4201 23.9969
Taekwondo 23.3750
Artistic Swimming 23.0000 22.8254
Diving 23.0000 24.1563
Skateboarding 19.5833

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

3. שאילתה מסוג CTE

שאלת המחקר: אילו מאמנים השיגו הכי הרבה מדליות? מדוע היא מעניינת: אנחנו רוצים לדעת אילו מאמנים השיגו הכי הרבה מדליות לרבות סוגי המדליות וענפי ספורט השונים.

WITH CoachMedalDetails AS (
    SELECT 
        a.coach,
        a.disciplines,
        SUM(CASE WHEN m.medal_type = 'Gold Medal' THEN 1 ELSE 0 END) AS gold_medals,
        SUM(CASE WHEN m.medal_type = 'Silver Medal' THEN 1 ELSE 0 END) AS silver_medals,
        SUM(CASE WHEN m.medal_type = 'Bronze Medal' THEN 1 ELSE 0 END) AS bronze_medals,
        COUNT(m.medal_type) AS total_medals
    FROM  Medallists m
    JOIN  Athletes a ON m.code = a.code
    WHERE a.coach IS NOT NULL AND a.coach != ''
    GROUP BY a.coach, a.disciplines
)
SELECT 
    coach,
    disciplines,
    SUM(gold_medals) AS gold_medals,
    SUM(silver_medals) AS silver_medals,
    SUM(bronze_medals) AS bronze_medals,
    SUM(total_medals) AS total_medals
FROM CoachMedalDetails
GROUP BY coach, disciplines
ORDER BY total_medals DESC, 
    gold_medals DESC, 
    silver_medals DESC, 
    bronze_medals DESC
limit 10

תוצאותיה:

Coach Disciplines Gold Silver Bronze Total
Club: Dean Boxall (AUS) [‘Swimming’] 8 6 3 17
National: Thierry Henry (FRA) [‘Football’] 0 17 0 17
National: Alyson Annan (AUS) [‘Hockey’] 0 16 0 16
National: Craig Fulton (RSA) [‘Hockey’] 0 0 16 16
National: Horst Hrubesch (GER) [‘Football’] 0 0 15 15
National: Eelco Meenhorst (NED) [‘Rowing’] 6 7 1 14
National: Andrew Randell (AUS) [‘Rowing’] 4 3 7 14
National: Arthur Elias (BRA) [‘Football’] 0 14 0 14
National: Fernando Ferrara (ARG) [‘Hockey’] 0 0 14 14
National: Jerome Daret (FRA) [‘Rugby Sevens’] 13 0 0 13

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

הסבר השאילתה

מה עושה השאילתה הזו?

השאילתה הזו נועדה לספק לנו תמונה ברורה על ההישגים של מאמנים שונים בתחומים ספורטיביים שונים. היא עושה זאת על ידי ספירת מדליות שזכו הספורטאים שהם מאמנים.

איך היא עושה את זה?

  1. יצירת טבלה זמנית: השאילתה מתחילה ביצירת טבלה זמנית בשם CoachMedalDetails. הטבלה הזו משמשת כבסיס לחישובים הבאים.
  2. חיבור טבלאות: היא מחברת שתי טבלאות: Medallists (רשימת הזוכים במדליות) ו-Athletes (רשימת הספורטאים). החיבור נעשה על סמך הקוד של הספורטאי, כדי לזהות איזה מאמן מאמן כל ספורטאי.
  3. ספירת מדליות: עבור כל מאמן וענף ספורט, השאילתה סופרת את מספר המדליות מכל סוג (זהב, כסף, ארד). היא עושה זאת באמצעות פונקציית SUM וביטויים מותנים (CASE WHEN).
  4. חישוב מדליות כולל: היא מחשבת את מספר המדליות הכולל של כל מאמן וענף.
  5. מיון התוצאות: השאילתה מדרגת את התוצאות לפי מספר המדליות הכולל, ולאחר מכן לפי מספר מדליות הזהב, הכסף והארד.
  6. הצגת התוצאות: לבסוף, השאילתה מציגה את 10 המאמנים המצליחים ביותר, כלומר אלו שזכו במספר הגדול ביותר של מדליות.

4. שאילתה עם UNION

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

SELECT  discipline, AVG(age) AS avg_age
FROM (
    SELECT m.medal_type, m.discipline, TIMESTAMPDIFF(YEAR, a.birth_date, m.medal_date) AS age
    FROM medallists m
    JOIN athletes a ON m.code = a.code
    WHERE m.medal_type = 'Gold Medal'
) AS sub
GROUP BY medal_type, discipline

UNION

SELECT 'All Sports' AS sport, AVG(age) AS avg_age
FROM (
    SELECT m.medal_type, TIMESTAMPDIFF(YEAR, a.birth_date, m.medal_date) AS age
    FROM medallists m
    JOIN athletes a ON m.code = a.code
    WHERE m.medal_type = 'Gold Medal'
) AS sub
GROUP BY medal_type;

תוצאותיה:

Discipline AVG_age
Shooting 27.5000
Rugby Sevens 25.7200
Judo 27.6071
Swimming 23.4247
Cycling Road 27.7500
Fencing 27.8667
Diving 22.7500
Cycling Mountain Bike 28.0000
Canoe Slalom 28.6667
Skateboarding 18.5000
Archery 25.4000
Equestrian 35.4667
Artistic Gymnastics 23.5455
Table Tennis 26.8000
Triathlon 26.5000
Cycling BMX Freestyle 23.5000
Rowing 28.0833
Athletics 25.6667
Cycling BMX Racing 28.5000
Trampoline Gymnastics 28.0000
Sailing 29.7143
Tennis 30.7500
Badminton 27.5000
Golf 27.5000
Surfing 22.0000
3x3 Basketball 30.1250
Cycling Track 26.5385
Wrestling 26.2667
Boxing 27.9231
Taekwondo 22.3750
Weightlifting 24.4444
Artistic Swimming 25.5556
Sport Climbing 25.2500
Hockey 26.4000
Canoe Sprint 28.3333
Marathon Swimming 28.5000
Breaking 26.0000
Football 24.0952
Beach Volleyball 24.0000
Volleyball 30.2308
Basketball 30.1667
Modern Pentathlon 24.0000
Handball 32.0000
Water Polo 26.5385
All Sports 26.5180

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

5. שאילתת חלון (Window Function)

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

SELECT 
    m.country,
    m.discipline,
    COUNT(m.medal_code) AS total_medals,
    SUM(COUNT(m.medal_code)) OVER (PARTITION BY m.discipline) AS total_medals_in_discipline,
    COUNT(m.medal_code) * 100.0 / SUM(COUNT(m.medal_code)) OVER (PARTITION BY m.discipline) AS percentage_of_medals
FROM 
    medallists m
GROUP BY 
    m.country, m.discipline
ORDER BY 
    percentage_of_medals DESC;

תוצאה:

Country Discipline Total Medals Total Medals in discipline Precentage of medals
France Cycling BMX Racing 3 6 50.00000
China Diving 15 36 41.66667
Korea Archery 12 30 40.00000
China Badminton 9 23 39.13043
China Table Tennis 11 30 36.66667
France Handball 17 47 36.17021
Netherlands Hockey 35 102 34.31373
Spain Artistic Swimming 9 27 33.33333
China Artistic Swimming 9 27 33.33333
United States Artistic Swimming 9 27 33.33333

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

  1. השאילתה מתחילה בספירת סך המדליות שכל מדינה זכתה בהן בכל ענף ספורט (באמצעות COUNT(m.medal_code)).
  2. באמצעות פונקציית החלון SUM(COUNT(m.medal_code)) OVER (PARTITION BY m.discipline), השאילתה מחשבת את סך כל המדליות שחולקו בענף הספורט הרלוונטי בכל המדינות יחדיו.
  3. השאילתה מחשבת את אחוז המדליות של כל מדינה בענף הספורט מתוך סך המדליות שחולקו באותו ענף, על ידי חלוקת סך המדליות של המדינה בסך המדליות בענף והכפלה ב-100.
  4. השאילתה מקבצת את הנתונים לפי מדינה וענף ספורט, ולאחר מכן מסדרת את התוצאות לפי אחוז המדליות בסדר יורד, כדי להציג אילו מדינות מצטיינות ביותר בענפים השונים.

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

View’s & Stored Procedure 🫣

יצירת View

CREATE VIEW athlete_medals AS
SELECT 
    a.code,
    a.name,
    a.country,
    m.medal_type,
    m.event
FROM 
    athletes a
JOIN 
    medallists m ON a.code = m.code;

כמה מילים על הצורך: View athlete_medals מספק מבט משולב על ספורטאים ומדליות שהם זכו בהן, כולל פרטים על סוג המדליה והאירוע.
השימוש ב-View זה מאפשר גישה נוחה למידע מקיף על הישגי הספורטאים ומסייע לניתוחי מידע שונים, כגון בחינת ביצועים לפי סוג המדליה.

Stored Procedure

ה-Stored Procedure בשם GetMedalCountByCountry נועד לספק דרך מהירה ונוחה לקבלת מספר המדליות הכולל של מדינה מסוימת.
פונקציה זו מאפשרת להפעיל שאילתה מותאמת אישית לפי המדינה המבוקשת, ומאפשרת קבלת תוצאות מהירה ואפקטיבית. היא שימושית לצורך ניתוח והשוואת ביצועי מדינות שונות באולימפיאדה.

DELIMITER //

CREATE PROCEDURE GetMedalCountByCountry(IN p_country VARCHAR(20))
BEGIN
  SELECT 
      m.country, 
      COUNT(*) AS total_medals
  FROM 
      medallists m
  WHERE 
      m.country = p_country
  GROUP BY 
      m.country;
END //

DELIMITER ;

סיכום 💡

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

אתגרים וקשיים

מבחינת קשיים אשר נתקלנו בהם, היו לא מעט:
בעיות ביצועים וקריסת ה-Workbench:
כאשר עבדנו עם כמות גדולה של נתונים שכללה את כל האתלטים והקבוצות, נתקלנו בבעיות ביצועים משמעותיות שהובילו לקריסת סביבת ה-SQL Workbench. בשל כך, נאלצנו לצמצם את כמות הנתונים בהם אנו מטפלים ולמקד אותם רק במדליסטים, כלומר אתלטים וקבוצות שזכו במדליות בלבד. זאת במטרה לשפר את ביצועי המערכת ולהימנע מקריסות נוספות.

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

נרמול עמודת האתלטים בצוות:
אחת הבעיות המרכזיות בה נתקלנו הייתה עמודת ה-athletes_codes בטבלת הקבוצות (Teams), אשר הכילה רשימה משרשרת של קודי אתלטים. מבנה זה לא אפשר ביצוע שאילתות יעיל והקשה על ניתוח המידע. כדי לפתור בעיה זו, החלטנו לנרמל את הנתונים באמצעות יצירת טבלה מקשרת חדשה בשם team_athletes. טבלה זו מאפשרת לשמור על קשרים ברורים בין אתלטים לקבוצות.

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

-- שלב 1: מחיקת קבוצות שלא זכו במדליות
DELETE FROM Teams
WHERE code NOT IN (
    SELECT DISTINCT team FROM Medallists
);

-- שלב 2: מחיקת אתלטים שלא זכו במדליות (באופן אישי או כחלק מקבוצה)
DELETE FROM Athletes
WHERE code NOT IN (
    SELECT DISTINCT code 
    FROM Medallists  -- אתלטים שזכו במדליות אישיות
)
AND code NOT IN (
    SELECT code FROM (
        SELECT a.code 
        FROM Athletes a
        JOIN Teams t ON INSTR(t.athletes_codes, a.code) > 0
    ) AS temp
);

-- שלב 3: אוכלוסיית הטבלה המקשרת team_athletes
INSERT INTO team_athletes (team_code, athlete_code)
SELECT 
    t.code, a.code 
FROM teams t
JOIN athletes a 
ON INSTR(t.athletes_codes, a.code) > 0;

-- מחיקת העמודה athletes_code והחלפתה בטבלת team_atheletes
ALTER TABLE Teams DROP COLUMN athletes_codes;

לאחר שצמצמנו את הנתונים למדליסטים בלבד כדי לשפר את ביצועי המערכת ולהימנע מקריסות, נותרה בפנינו השאיפה להשתמש במלוא הנתונים המקוריים, כלומר לכלול גם את כל האתלטים והקבוצות שהשתתפו באולימפיאדה, ולא רק את אלו שזכו במדליות. באמצעות אופטימיזציה של הסקריפט לאכלוס הטבלה המקשרת team_athletes וטעינת המידע בשלבים, הצלחנו לבסוף להשתמש במידע כולו, ובכך לשמור על ניתוח כוללני ומקיף של הנתונים.

תובנות

  • זאת לא התוצאה אלא הדרך - התמודדנו עם קשיים שגרמו לנו לחשוב מחוץ לקופסא ולייצר לעצמנו פתרונות מורכבים.
  • היכולת שלנו להמיר נתונים טבלאיים למסד רלציוני השתפרה באופן מדהים.
  • השתפרה גם היכולת לשאול שאלות ולהסיק מסקנות מתוך הנתונים.

ועכשיו מילות סיכום

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

אנחנו מקווים שנהנתם לקרוא את הפרוייקט. לכל שאלה ניתן לכתוב לנו במייל: Dolev[@]Ravid.email