איך עושים JOIN?
-
בהמשך לשאלה הנ"ל
לפעמים יש משתמשים שלא רשומים ב userinfo
אבל אני בכל זאת אני רוצה לקבל את הרשומה שלהם בpoints
איך אני כותב את השאילתא? -
LEFT JOIN זה למקרה שאתה רוצה את כל השורות של הטבלה שצויינה ראשונה (שזה לשמאל הביטוי JOIN). למקרה הפוך יש RIGHT JOIN. הברירת מחדל היא INNER שזה רק הזהים, ויש את FULL שזה הכל משני הצדדים. בחלק ממסדי הנתונים האחרון לא נתמך.
-
@OdedDvir אמר באיך עושים JOIN?:
אולי עדיף לא להשאיר את הדבר בידיים של הDB איפה שאפשר בקלות לקבוע את הסדר כדלעיל?
זה לגיטימי לעיתים נדירות, אחרת הרסת את כל הרעיון של SQL ("תגיד מה אתה רוצה, אני אדאג לאיך").
מקרה שבו הDB כ"כ מזייף הוא משונה מאוד. ב99% מהמקרים הDB חכם מספיק לעשות את הסדר הכי טוב. -
OdedDvirהשיב לdovid ב 10 באוג׳ 2020, 9:59 נערך לאחרונה על ידי OdedDvir 8 באוק׳ 2020, 10:01
@dovid אמר באיך עושים JOIN?:
זה לגיטימי לעיתים נדירות, אחרת הרסת את כל הרעיון של SQL ("תגיד מה אתה רוצה, אני אדאג לאיך").
אני עדיין אוחז ב"תגיד מה אתה רוצה ועדיין תדאג"...
מקרה שבו הDB כ"כ מזייף הוא משונה מאוד. ב99% מהמקרים הDB חכם מספיק לעשות את הסדר הכי טוב.
מעניין לראות את תוכנית הריצה של השאילתא הארוכה. אם @nigun יוכל להראות אותה כאן (כמובן רק אם זה לא ידרוש שוב חצי שעה...)
-
@OdedDvir אמר באיך עושים JOIN?:
@dovid אמר באיך עושים JOIN?:
זה לגיטימי לעיתים נדירות, אחרת הרסת את כל הרעיון של SQL ("תגיד מה אתה רוצה, אני אדאג לאיך").
אני עדיין אוחז ב"תגיד מה אתה רוצה ועדיין תדאג"...
זה לא נורמלי, במקרים רגילים אמורים להיות רגועים לחלוטין.
מצב בו חושבים מה יותר יעיל בכל שאילתה אינו הגיוני כי SQL מסתיר המון מידע, פרטים פיזיים וטכניים שקריטיים לאיך לבצע את השאילתה. כל עוד הוא אחראי אתה סומך על ידיעותיו, אבל אם אתה נהיה "אחראי" למיטוב השאילתות, אתה מגשש באפילה עם סברות שלא תמיד בקנה אחד עם המצב הטכני של הנתונים. -
@dovid אמר באיך עושים JOIN?:
זה לא נורמלי, במקרים רגילים אמורים להיות רגועים לחלוטין.
אני משער שכך הוא בבסיסי נתונים מקצועיים.
לצערי אני מגיע משדה הקרב של Access, שם Jet לא מגיע לרמות של אופטימיזציה כזו, נוכחתי לדעת ששאילתא שלקחה לי למעלה מ-4 דקות עם הרבה Join-ים הפכה ל-3 שניות כשסידרתי אותה מחדש (עם טבלאות זמניות וכו').נו, עוד מסמר בארון של אקסס...
-
OdedDvirהשיב לdovid ב 10 באוג׳ 2020, 10:29 נערך לאחרונה על ידי OdedDvir 8 באוק׳ 2020, 10:30
@dovid אמר באיך עושים JOIN?:
אתה מדבר על שאילות רציניות מאוד
נכון, היו שם לפחות 20 Join-ים של שאילתות שונות.
לפי זכרוני עיקר הבעיה שם הייתה שהייתה שאילתא מאוד בסיסית שעושה סינון על טבלה (כדי לשלוף רק את הנתונים הרלוונטיים למערכת) והרבה מהשאילתות הנ"ל התבססו עליה (כדי לחשב כל אחת את הדרוש לה) ואח"כ בוצע Join. זה גרם קריאות רבות לאותה שאילתא, והפתרון היה טבלת עזר זמנית. -
@OdedDvir אמר באיך עושים JOIN?:
מקרה שבו הDB כ"כ מזייף הוא משונה מאוד. ב99% מהמקרים הDB חכם מספיק לעשות את הסדר הכי טוב.
מעניין לראות את תוכנית הריצה של השאילתא הארוכה. אם @nigun יוכל להראות אותה כאן (כמובן רק אם זה לא ידרוש שוב חצי שעה...)
לא אכפת לי להעסיק את המכונה שלי לעוד חצי שעה (תופס סך הכל ליבה אחת)
אבל אני לא יודע איך מציגים את התוכנית ריצה? -
@OdedDvir
נראה שזה לא זמין בגירסת MYSQL שלי
אז עשיתי EXPLAIN EXTENDED+----+-------------+----------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ | id | select_type | table | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ | 1 | SIMPLE | userinfo | ALL | NULL | NULL | NULL | NULL | 30410 | 100.00 | NULL | | 1 | SIMPLE | points | ALL | NULL | NULL | NULL | NULL | 359834 | 100.00 | Using where; Using join buffer (Block Nested Loop) | +----+-------------+----------+------+---------------+------+---------+------+--------+----------+----------------------------------------------------+ -
@nigun הסתקרנתי פתאום יותר אז עליתי לראות את מבנה הנתונים.
הוא לא היה קריא (ולכן עזבתי בפעמים הקודמות שביקרתי את הנושא, בלי לבדוק...)
ערכתי את הודעתך ועיצבתי את הקוד.
ובכן, השאלה שמייד עולה זה למה לעשות JOIN בין שני עמודות שאינם שדה מפתח. למה השדה user בpoints לא מצביע על הid של שבטבלה userinfo? (ואיך זה שאורכי השדות של הvarchar בשני שדות הuser לא זהים, זה לא כ"כ הגיוני).אגב גירסת הmysql: בכל אובנטו מתקינים בד"כ mysql כמו ילדים טובים מהמנהל חבילות ונתקעים עם הגירסה המיושנת 5 (אוחזים כעת ב12!!). לתשומת לבכם בהתקנת השרת הבאה שלכם. לגירסה 12 יש המון פיצ'רים שאין ב5.
-
@dovid
לא תכננתי בהתחלה לעשות להם JOIN
ויצרתי את הטבלות בזמנים שונים, לא זוכר למה ננתי ערכים שונים (כנראה אין סיבה מוצדקת).
ובכלל הידע שלי במסדי נתונים דל מאוד (לצערי)
ועד שאני לא נתקע אני לא שואל,
אז אני אשאל עכשיו: מה זה שדה מפתח? ולמה הוא משמש? -
@nigun ממש בראשי פרקים כדי לא לחרוג מהנושא של האשכול:
זה השדה שאמור לזהות את הרשומה. הוא תמיד ייחודי (ללא כפילויות בין הרשומות בטבלה) ובדרך מוסכמה הוא נקרא ID ולרוב הוא מסוג LongInt (יש גם מקרים יותר נדירים של שימוש ב GUID)הוא השדה שאמור להיות המקשר הקלאסי בין טבלאות בשאילתות, כלומר שלרוב עליו מבצעים את ה-Join.
הוא גורם מכריע בנירמול של בסיסי נתונים, שזה במילים פשוטות, התהליך שבו אני בונה את הDB בצורה שממזערת ככל שניתן את הכפילויות בנתונים. נושא שראוי לאשכול נפרד.
-
@nigun לא אוהב את זה, אני חושב שזה לא הוגן.
אתה יכול לבחור דרך של ללמוד תוך כדי עשייה,
אבל לבוא לאנשים בשאלה י' בלי שהם יידעו שאתה לא יודע את הט' הקודמים, זה כבר משגע.
מלבד זאת, הבנה בסיסית של מסדי נתונים היא כה קלה (אפשר לתמצת אותה בכמה שורות של טקסט) שנראה לי יש לך אובססיה לדרך הזו של ללמוד תוך כדי. -
@dovid
באופן כללי אתה צודק.
אבל במקרה הזה לא נראה שזה קשור
כי השדה USER הוא לא יחודי (אם הבנתי נכון את ההגדרה של מפתח)
וגם אם אני משנה אורך השדות שיהיו שווים, זה לא פותר את הבעיה (השאילתא עדיין רצה).
או שלא הבנתי את ההודעה הקודמת שלך (סביר מאד)
21/56