לפעמים החיים מזמנים לך שאילתות לא רגילות, שהתשובה אליהן לא בדיוק ברורה. אחת כזו היא שאילתת sql שמחפשת ערכים שלא נמצאים בטבלה.
לדוגמא ניקח טבלה א, בה יש רשימת אנשים, וטבלה ב בה יש אנשים שקיבלו אישור שהייה בארץ. איך שולפים את האנשים שלא קיבלו אישוור? נניח לרגע שאי אפשר להכניס לטבלה השניה רשימת לא מאושרים.
התשובה היא זו:
SELECT * FROM tbl1 LEFT JOIN tbl2 ON tbl1.personId = tbl2.personId WHERE ISNULL(tbl2.personId)
או במילים אחרות – שלוף את כל הנתונים מטבלה אחת המחוברת לשניה, כשבשניה הID הוא null.
יפה
הקונספט נכון אבל השתמשת ב INNER JOIN – מה שיגרום לכך שיחזרו אך ורק רשומות הנמצאות בשתי הטבלאות.
השאילתא חייבת להשתמש ב LEFT OUTER JOIN על-מנת להחזיר גם רשומות שלא נמצאות בטבלא הימנית (tbl2). השאילתא הנוכחית חסרת משמעות ולעולם לא תחזיר שום תוצאה.
Saggi,
אם בטבלה השנייה יש את כל הרשומות של האנשים שקיבלו אישור, אז inner join באמת יוציא את כל מי שקיבל, ולא תוצאה ריקה.
ליאור,
א. בבעיה עליה אתה מדבר אנחנו רוצים שהשאילתא תחזיר רשומות ש*לא* נמצאות בטבלא ב', לא? ביקשת לשלוף את האנשים ש*לא* קיבלו אישור.
ב. השאילתא שלך *לעולם* לא תחזיר ערכים, גם לא ערכים הנמצאים בשתי הטבלאות. לא הגיוני שהשאילתא תדרוש ISNULL על tbl2.personId בזמן שהיא גם דורשת tbl1.personId = tbl2.personId.
הרי NULL לעולם לא יהיה שווה לשום ערך, אפילו לא ל NULL. השאילתא שלך דורשת ש tbl2.personId יהיה גם שווה לערך כלשהו וגם יהיה NULL.
פיספסת את הנקודה. אם הערך קיים בשתי הטבלאות לא מוחזר כלום. אם הוא קיים רק ב״ימנית״ הinner יכשל כפי שאתה אומר ויחזיר null, לכן השאילתה תחזיר את הערך הרצוי.
ניסית לבדוק לרגע וזה נכשל?
INNER JOIN מחזיר אך ורק רשומות העונות לתנאי ה ON.
על-מנת להחזיר רשומות שנמצאות רק באחת מהטבלאות צריך להשתמש ב OUTER JOIN, לא INNER JOIN.
אתה ניסית להריץ את זה וקיבלת איזשהי שורה?
אם תצליח לקבל ולו שורה אחת עם השאילתא המדוייקת הזאת, עם כל שתי טבלאות שתרצה – הרי שמצאת באג ב MySQL.
למען הסר ספק – כשאני אומר שלא תחזיר שום שורה אני מתכוון לכך שהיא גם לא תחזיר שום שורה עם NULL.
אני לא יודע למה אתה מגדיר שאילתא שמחזירה NULL כ'שאילתא שנכשלה'
שגיא, אתה צודק – בדקתי שוב את השאילתא המקורית והשתמשתי בLEFT, כשאצליח להגיע מול מחשב אבדוק מה קורה עם השאילתא הזו.
לקח לך הרבה זמן לבדוק את עצמך.
יכלת לפחות לטרוח לבדוק מה זה באמת INNER JOIN מול OUTER JOIN כבר אחרי התגובה הראשונה שכתבתי לך
שגיא, חשבתי אם למחוק את התגובה שלך סתם כי היא לא נחמדה אבל בסוף השארתי כי בכל זאת טרחת ובאת לתקן. האמת שאת רוב ההתכתבות איתך עשיתי דרך האייפון מרחוק, ובדקתי ברגע שהייתי ליד מחשב.