Sub Queries

מישהי139

New member
Sub Queries

היי,
אשמח לקבל בבקשה הסבר לגבי השאילתה הבאה:

SELECT last_name, salary
FROM employees e
WHERE 3 > (SELECT COUNT(*)
FROM employees
WHERE e.salary < salary);

כיצד זה עובד צעד אחר צעד מאחורי הקלעים?
לא מצליחה להבין...
 

Juventini1

New member
תשובה

היי,
כמו ששמת לב השאילתה מורכבת משני חלקים:
החלק הפנימי שמתבצע קודם מבחינת סדר הפעולות. השאילתה הפנימית סופרת לכמה employees יש salary שהוא גדול מ-salary (שאני חייב להודות שלא ירדתי לסוף דעתך בחלק של ה- WHERE). ואז על התשובה שחזרה לך, את מציגה את כל ה-employees שה- salary שלהם גדול מ- 3. כלומר בעצם יש לך פה ביטוי לוגי, שבמקום לערוך השוואה בין מספר לפרמטר (לדוגמא: 2 > @i), את עורכת השוואה בין ערך מסוים מסוים לבין התוצאה שתחזור מהשאילתה הפנימית. זוהי גם מגבלה של Sub query מסוג זה, תמיד בשאילתה הפנימית חייב לחזור ערך אחד בלבד!
החלק שני, החיצוני, הוא שאילתה פשוטה למדיי שבו את פשוט מציגה את את שם המשפחה והמשכרות של כל העובדים שלהם יש משכורת הגדולה מ- 3.
לסיכום להלן השלבים:
1. ביצוע השאילתה הפנימית
2. ביצוע ההשוואה הלוגית של Salary גדול מ- 3.
3. ביצוע השאילתה החיצונית ע"י הצגה של המידע המבוקש אחרי הסינון שהצבת בסעיף 2 לעיל.
מקווה שעזרתי
 

מישהי139

New member
תודה רבה לכולם על התשובות ועל ההתייחסות.

לכשאסיים את יום העבודה אנסה להבין את שכתבתם.
 

גרי רשף

New member
מסובך..

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

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

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

התנאי שמספרם קטן מ-3 הוא ב-Where של השליפה החיצונית.
התנאי שמשכורתם גבוהה משלו הוא ב-Where של השליפה הפנימית.

שימי לב שבתנאי הפנימי e.salary השמאלי מתייחס לשליפה החיצונית (ולכן- e),
ו-salary הימני לשליפה הפנימית.

מסובך- זה לא את זה הם..
 

גרי רשף

New member
אופס- לא שמתי לב ש-Juventini1 ענה..

מקווה שלפחות אחד משנינו יהיה לך לעזר.
 
אגב

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

pitoach

New member
זה נכון אבל לא תמיד

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

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

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

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

pitoach

New member
בכיף

 
למעלה