האנטומיה של שאילתת SQL- תגובות
-
@nigun אמר בהאנטומיה של שאילתת SQL- תגובות:
אבל השאילתא
SELECT * FROM info GROUP BY user HAVING id > 10000;
תעבוד.ב-postgres זה לא יעבוד. גם במנועים אחרים אם זה יעבוד (ואני לא בטוח שזה חוקי בשום מנוע) לא יהיה לזה שום משמעות כי ה-id לא מוגדר אם לא עשית קיבוץ לפי id.
וכנ"ל
SELECT * FROM info HAVING id > 10000;אז השאלה שלי עכשיו, למה לא להשתמש תמיד בHAVING ?
כנ"ל. HAVING בלי GROUP BY עושה קיבוץ אוטומטי של כל השורות לשורה אחת. אם כן ל-id אין משמעות
-
@nigun אמר בהאנטומיה של שאילתת SQL- תגובות:
אז השאלה שלי עכשיו, למה לא להשתמש תמיד בHAVING ?
מבחינת יעילות, לענ"ד אין להשתמש ב HAVING אם אפשר להשתמש ב- WHERE, מפני שה-WHERE הוא מסנן מוקדם ברמת השורה, ומתבצע לפני הקיבוץ, וכך הקיבוץ מתבצע על קבוצה קטנה יותר (תוצאת ה-WHERE) לעומת זאת ה-HAVING הוא מסנן מאוחר ברמת קבוצה, ויתבצע על כל הרשומות.
-
-
@yossiz
יצאתי מבולבל@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
לא תראה תוצאה כי השאילתה לא חוקית כי אסור להזכיר עמודה שהוא לא חלק מה-group by אם לא על ידי פונקצית aggregation.
@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
אפשר, אבל זה עושה קיפול מובן (implicit) של כל השורות לשורה אחת
יש תוצאה או לא?
ואיך נכנס לכאן implicit? -
@nigun אתה צודק, סתרתי את עצמי. כי לא בדקתי את ההתנהגות של כל המנועים וניסיתי לנחש מה יהיה ההתנהגות של mysql, הניחוש לא יצא כל כך מוצלח
יש תוצאה או לא?
אין.
ואיך נכנס לכאן implicit?
כי לא עשית קיבוץ בפירוש על ידי
GROUP BY
אז הקיבוץ הוא "לא מפורש" או "מרומז" או "משתמע" או איך שתקרא לזה... מזה שעשית סינון על התוצאה של הקיבוץ על ידיHAVING
. -
@nigun בא נעשה פה סדר,
יש שינוי התנהגות בין mysql ל-sql server ו-postgres במקרה של HAVING בלי קיבוץ
mysql מתייחס לזה כ-where
השניים האחרים מתייחסים לזה כרמז שאתה רוצה קיבוץ ולכן כל השורות מתקפלות לשורה אחת מקובץ. זה ברור? ב-mysql תקבל שורות מרובות (אם יש יותר משורה אחת שעונה על הקריטיריונים), בשניים האחרים אתה לא תקבל יותר משורה אחת!!!
זה הבדל ראשון
עכשיו במקרה של שורה מקובצת מכמה שורות, יש גם הבדלי התנהגות בין המנועים אם מותר להזכיר שם עמודה שהוא לא חלק מהקיבוץ (למרות שאין לו ערך מוגדר אחרי הקיבוץ).
mysql מתייחס לזה בצורה סלחנית ומתיר את זה. (איזה ערך מוחזר? הרי השורה מקובצת מכמה שורות? אני לא יודע...)
postgres ו-sql server זורקים שגיאה.
אלו היסודות ואידך פירושא זיל גמור. -
@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
mysql מתייחס לזה בצורה סלחנית ומתיר את זה. (איזה ערך מוחזר? הרי השורה מקובצת מכמה שורות? אני לא יודע...)
postgres ו-sql server זורקים שגיאה.https://dev.mysql.com/doc/refman/5.7/en/group-by-handling.html
אני מבין שהתוצאה עקבית (כל עוד אין שינוי שורות בטבלה) אך בלתי צפויה. זה בפועל חוסך גם ביצועים (אל תחפש לא MAX ולא MIN, תביא משהו וזהו) והמון תחביר מייגע... אבל השאילתה לא הכי קריאה והגיונית. -
@dovid תודה. חיפשתי קצת בתיעוד ומשום מה לא הצלחתי למצוא את זה.
אני מבין מהתיעוד שמגירסה 5.7.5 ואילך ההתנהגות היא מאוד הגיונית וידידותית.
מצב ONLY_FULL_GROUP_BY מופעל בברירת מחדל. שזה אומר שאסור לבקש עמודות בשורות מקובצות אם אין ערך מוגדר לעמודה.
אבל יש לוגיקה די טובה (אומנם לא מושלמת) שמזהה אם יש ערך מוגדר לעמודה או לא.
זה מזוהה כערך מוגדר באחד משני דרכים.
א) על ידי זיהוי functional dependence על עמודה שנמצא בתנאי הקיבוץ, שזה אומר מצב שבו ערך העמודה מחוייב לערך מסויים לפי עמודה שנמצא בתנאי הקיבוץ (סליחה על ההסבר הלא ברור...).
ב) אם בחרת את ערך העמודה ב-WHERE
.בגירסה 5.6 (או 5.7.4) ההתנהגות סלחנית במידה שזה יחזיר ערכים רנדומליים אם אין משהו הגיוני להחזיר. (אני מבין שעשו את זה בגלל שלא היתה לוגיקה טובה לזהות אם יש ערך מוגדר לעמודה או לא, לכן סמכו על המשתמש)
לא מצאתי רמז לזה שהתוצאה עקבית. וגם לא ברור לי מה היתרון בזה שזה עקבי אם היא בלתי צפויה.
-