• בלוג
  • ואז נתתי ל Chat GPT לכתוב לי את ה SQL

ואז נתתי ל Chat GPT לכתוב לי את ה SQL

01/02/2023

סיפרתי לכם כבר על התעודות שהוספתי לאתר, ואיך כתבתי שאילתת SQL לא מאוד מתוחכמת כדי להבין אם משתמש ראה את כל השיעורים בקורס כדי לדעת אם אפשר לשלוח תעודה.

אלא שאז כמה אנשים ביקשו אפשרות להדפיס תעודות ישנות, כלומר תעודות על קורסים שהם כבר לא יכולים לגשת אליהם כי המנוי שלהם נגמר. הפיתרון לזה היה לייצר מסך "רשימת תעודות" שיראה לכם במקום אחד את כל הקורסים שסיימתם עם אפשרות להוריד תעודה לכל קורס. אבל עכשיו יש לנו בעיה חדשה - השאילתה שבודקת אם תלמיד סיים קורס תלויה במזהה הקורס. הפעלה שלה בלולאה על כל הקורסים מייצרת את באג N+1 הידוע לשימצה. הגיע הזמן לעדכן את השאילתה כדי להוציא את כל הקורסים שתלמיד סיים.

האתגר בקצרה ברמת הטבלאות נשמע כך-

  1. יש טבלה בשם bundle שמחזיקה נתונים על קורסים. אנחנו רוצים לקבל את ה id של כל הקורסים שתלמיד סיים.

  2. יש טבלה בשם lessons שמחזיקה את כל השיעורים. לכל שיעור גם יש id ובגלל ששיעור שייך לקורס יש לו גם bundle_id.

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

  4. טבלה אחרונה בסיפור היא users. אנחנו מתחילים עם id מסוים מטבלה זו.

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

SELECT bundles.id
FROM bundles
JOIN lessons ON bundles.id = lessons.bundle_id
WHERE NOT EXISTS (
  SELECT *
  FROM lessons AS l
  LEFT JOIN user_in_lesson AS uil ON l.id = uil.lesson_id
  WHERE uil.user_id = [user_id] AND l.bundle_id = bundles.id
) IS NULL;

ונכון, היא לא עובדת, אבל היי יש פה רעיון מעניין, באמת אפשר להשתמש ב Sub Queries כדי לרוץ על כל הקורסים בלולאה בתוך בסיס הנתונים. רק צריך לתקן את תתי השאילתות ומגיעים לגירסה שבסוף הכנסתי לאתר (מתורגמת כבר לריילס):

@bundles = Bundle
.joins(:lessons)
.where("
  (SELECT count(*)
   FROM lessons AS l
   LEFT JOIN user_in_lessons AS uil ON l.id = uil.lesson_id
   WHERE uil.user_id = ? AND l.bundle_id = bundles.id)
   =
  (SELECT count(*) FROM lessons where lessons.bundle_id = bundles.id)", user_id).distinct

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

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