טעויות SQL נפוצות שעושים ג'וניורים (א') – Null Values

הרשמו לניוזלטר

טיפים, מדריכים וחדשות ישירות למייל בניוזלטר חודשי

טעויות בתחום ניתוח נתונים קורות לכולם, כל הזמן, ללא קשר לוותק שלכם כדאטה אנליסטס. הבעיה האמיתית מתחילה עם טעויות שאנחנו לא יודעים שבכלל עשינו. אנליסטים ג'וניורים, בהיותם חדשים בתחום ניתוח הנתונים, חשופים מאוד לאפקט 'דאנינג קרוגר' – הטייה קוגנטיבית נפוצה, שבה אנחנו חושבים שאנחנו מתמצאים בתחום הרבה יותר ממה שאנחנו באמת מתמצאים בו. בעיני ג'וניור, SQL יכולה להיראות כשפה מאוד פשוטה straight forward. בהיותה שפה דקלרטיבית, היא עלולה ליצור לסיטואציות של חוסר הבנה בין המשתמש (כלומר, אתם) לבין המחשב. במקרה הטוב זה יביא להרבה בלבול ("למה לעזאזל יש בטבלה הזאת פי 5 שורות ממה שציפיתי שיהיו?") במקרה הרע זה עלול להביא הצגה מסולפת של המציאות.

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

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

עבודה עם Null Values

אחד הנושאים המבלבלים ביותר בעבודה עם דאטה קשור לעבודה עם ערכי Null. לא אלאה אתכם בפרטים של של איך ולמה נוצר הקונספט של ערך Null (למרות שזה ממש מעניין), אבל מסיבות רבות ישנה הסכמה כי Null כקונספט, יוצר המון בעיות. מה שחשוב להכיר הוא שNull אינו Data Type אמיתי. למעשה אפשר להסתכל עליו כNon-Value.

Null מייצג שדה ריק – הוא לא מייצג '0' וגם לא מייצג blank space. בואו נראה איזה בעיות זה עלול ליצור לנו.

טעות #1 – שימוש בComparative Operators על Null

כאנליסטים יוצא לנו לעשות השוואות על שדות מסוג String וכן על שדות מספריים (Int, float וכו') באמצעות '>', '<' או '='. מכיוון שאמרנו שNull הוא Non Value, לא 0 ולא blank space, אי אפשר להשוות אליו ערך אחר (אגב, גם אי אפשר להשוות Null לNull 🤯). הטעות הכי חמורה של אי התייחסות לעמודה שמכילה Null תיווצר בפקודת WHERE. אסביר זאת עם כמה דוגמאות.

נתונה הטבלה הבאה של לקוחות החברה:

SELECT *
FROM customers
AGEADDRESSLAST_NAMEFIRST_NAMEID_NUMBER
19Tel AvivGurRoey301524646
22HaifaBarakDavid217352689
25HaifaCohenNoa 102354646
25Tel AvivFeldmanNadav301857456
33NullMosheDafna105235689
NullNullLevyItay201567842

אם אנסה לחפש בDB את לקוחות החברה שהכתובת שלהם אינה Tel Aviv, יתכן ואכתוב שאילתא כזו:

SELECT *
FROM customers
WHERE [address] <> 'Tel Aviv'
AGEADDRESSLAST_NAMEFIRST_NAMEID_NUMBER
22HaifaBarakDavid217352689
25HaifaCohenNoa 102354646

כפי שאתם רואים סיננתי בטעות שני לקוחות שכתובתם הייתה Null – זאת משום שSQL מתעלם מכל סוג של Comparison Operations על Null (מאחורי הקלעים, הוא מתייחס לזה כUnkonwn ולא מציג את התוצאה).

שאילתא נכונה יותר הייתה צריכה לכלול התייחסות לערכי Null:

SELECT *
FROM customers
WHERE [address] <> 'Tel Aviv' OR [address] IS NULL
AGEADDRESSLAST_NAMEFIRST_NAMEID_NUMBER
22HaifaBarakDavid217352689
25HaifaCohenNoa 102354646
33NullMosheDafna105235689
NullNullLevyItay201567842

אותו קונספט חל על השוואת Null לכל דבר אחר. הנה דוגמא של השוואה על שדה מספרי באותה טבלה (Int):

SELECT *
FROM customers
WHERE AGE > 20
AGEADDRESSLAST_NAMEFIRST_NAMEID_NUMBER
22HaifaBarakDavid217352689
25HaifaCohenNoa 102354646
25Tel AvivFeldmanNadav301857456
33NullMosheDafna105235689

כפי שניתן לראות, שני ערכים סוננו מחוץ לטבלה: רועי גור בן ה19, ואיתי לוי שגילו בטבלה הוא Null. השוואה לNull איננה אפשרית כי Null אינו data type "אמיתי" ולכן SQL התעלם מתוצאה זו.

טעות #2 – ביצוע פעולה חישובית על Null

כל פעולה חישובית (חיבור, חיסור, חילוק, הכפלה) על ערך Null אינה אפשרית משום שהוא Non-Value. לשם הדוגמא, Null * 10 לא שווה 10, אלא Null.

SQL יחזיר פעולת חישוב על Nulll כNull. למה? כי Null מייצג ערך לא קיים.

10 * כלום = כלום.

אם נחזור לטבלת הדוגמא שלנו, חישוב על ערך Null יראה כך:

SELECT ID, FIRST_NAME, LAST_NAME, AGE, AGE * 10
FROM customers
AGEAGEADDRESSLAST_NAMEFIRST_NAMEID_NUMBER
19019Tel AvivGurRoey301524646
22022HaifaBarakDavid217352689
25025HaifaCohenNoa 102354646
25025Tel AvivFeldmanNadav301857456
33033NullMosheDafna105235689
NullNullNullLevyItay201567842

טעות #3 – אגרגציה ללא התייחסות לNulls

כפי שאמרנו (שוב ושוב 😉 ), מבחינת המחשב שלכם, Null מייצג שדה ריק. כשנעשה אגרגציה, SQL יפיל ערכים מסוג Null ויצור מעין עיוות בנתונים שיתכן שלא התכוונו אליו.

אדגים בעזרת דוגמא פשוטה שנוצרת לעיתים בעקבות שימוש בLEFT JOIN.

SELECT Client_name, Revenue
FROM managed_clients left join client_revenues
ON managed_clients.client_id = client_revenue.client_id
RevenueClient_name
100Vandalay Industries
200The Human Fund
NullDr. Martin Van Nostrand

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

SELECT AVG(Revenue)
FROM managed_clients left join client_revenues
ON managed_clients.client_id = client_revenue.client_id
AVG
150

מכיוון שDr. Martin Van Nostrand לא ביצע עסקאות, הוא קיבל את הערך NULL. ניתן לראות שחישוב הממוצע התבצע על שני הערכים שאינם Null וערך הNull סונן החוצה לפני ביצוע החישוב. כשSQL מבצע אגרגציה, הוא לא מתייחס לערך Null כ-0 למרות שיתכן שלזה התכוונו כשביקשנו למצוא ממוצע לכל חודש. אנחנו נרצה להכליל את הלקוח עם ערך הNull בחישוב הממוצע כי הוא לקוח מנוהל שחשוב לנו להתייחס אליו באנליזה.

מה עושים כדי לפתור את זה? משתמשים בפונקציית isnull. פונקציה שימושית מאוד שכופה על SQL את הלוגיקה הבאה: אם הערך הוא Null תהפוך אותו לX. במקרה שלנו, נרצה להפוך אותו ל0.

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

ניתן לראות כי כאן השתמשתי ב0 ועכשיו החישוב כלל גם את ההכנסה שלא התקבלה מDr. Martin Van Nostrand.

SELECT  AVG(ISNULL(Revenue), 0)
FROM managed_clients left join client_revenues
ON managed_clients.client_id = client_revenue.client_id
AVG
83.3333

Take Home Message

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

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

חושבים על טעויות נפוצות אחרות? אשמח לשמוע בתגובות.

הרשמו לניוזלטר

טיפים, מדריכים וחדשות ישירות למייל בניוזלטר חודשי
שתף

תוכן עניינים

3 2 votes
Article Rating
Subscribe
Notify of
guest
2 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
אפרת

סחטיין, העברתי לג׳וניורים אצלנו והם אהבו מאד!

Ori

אהבתי, מעביר לקבוצה

2
0
Would love your thoughts, please comment.x
()
x