האנטומיה של שאילתת SQL- תגובות
-
@nigun אין הבדל בפעולה עצמה. כל ההבדל הוא במיקום בקו הייצור שבו זה מתבצע.
כל פעולה מתבצעת על התוצאה של הפעולה הקודמת.
WHERE
מסנן את השורות של הטבלה שהתקבלה מה-FROM
(כולל ה-JOIN
-ים).
HAVING
מסנן את הטבלה שמתקבלת אחרי הקיבוץ שלGROUP BY
. -
@nigun אה, עכשיו אני מבין במה אתה מתקשה.
התשובה היא שלפני הקיבוץ אי אפשר לסנן לפי תוצאה של פונקציה שמסכמת את כל השורות המקובצות. -
אני צריך לתקן קצת במאמר שלי. כתבתי שאחרי קיבוץ אי אפשר להזכיר ערך של שורה ספציפית רק ערך של פונקציה שמסכמת באיזשהו צורה את כל השורות המקופלות בשורה זו. זה לא לגמרי נכון, כי אפשר להזכיר את הערך של העמודה שלפיה עשית את הקיבוץ מכיון שהערך שווה לכל השורות המקובצות. (בחלק מהמנועים אפשר להזכיר ערכים של עמודות אחרות אבל אין לזה משמעות ברורה).
אני לא יודע אם הדבר הזה בלבל אותךמשמע שזה משמש גם בשביל GROUP BY וגם בשביל שאר הערכים שמתקבלים מתוך פונקציה.
אני לא בטוח שאני מבין לאיזה שני דברים אתה מתכוון.
האם זה אומר שיש אופציה שישתמשו בHAVING בלי GROUP BY?
אפשר, אבל זה עושה קיפול מובן (implicit) של כל השורות לשורה אחת
-
אני צריך לתקן קצת במאמר שלי. כתבתי שאחרי קיבוץ אי אפשר להזכיר ערך של שורה ספציפית רק ערך של פונקציה שמסכמת באיזשהו צורה את כל השורות המקופלות בשורה זו. זה לא לגמרי נכון, כי אפשר להזכיר את הערך של העמודה שלפיה עשית את הקיבוץ מכיון שהערך שווה לכל השורות המקובצות. (בחלק מהמנועים אפשר להזכיר ערכים של עמודות אחרות אבל אין לזה משמעות ברורה).
אני לא יודע אם הדבר הזה בלבל אותךמשמע שזה משמש גם בשביל GROUP BY וגם בשביל שאר הערכים שמתקבלים מתוך פונקציה.
אני לא בטוח שאני מבין לאיזה שני דברים אתה מתכוון.
האם זה אומר שיש אופציה שישתמשו בHAVING בלי GROUP BY?
אפשר, אבל זה עושה קיפול מובן (implicit) של כל השורות לשורה אחת
@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
אני לא בטוח שאני מבין לאיזה שני דברים אתה מתכוון.
group or aggregate
האם זה אומר שיש אופציה שישתמשו בHAVING בלי GROUP BY?
אפשר, אבל זה עושה קיפול מובן (implicit) של כל השורות לשורה אחת
לא הבנתי
נראה לי שאני צריך לנסות על טבלה אמיתית וזהו. -
עכשיו נראה לי שעכשיו אני מבין
פשוט לא שייך לעשות aggregate אם אין group (אולי אפשר אבל אין לזה משמעות)וחוץ מזה השאילתא
SELECT * FROM info GROUP BY user WHERE id > 10000;
לא תעבוד, כי אי אפשר לעשות WHERE אחרי הGROUP.
אבל השאילתא
SELECT * FROM info GROUP BY user HAVING id > 10000;
תעבוד.
וכנ"לSELECT * FROM info HAVING id > 10000;
אז השאלה שלי עכשיו, למה לא להשתמש תמיד בHAVING ?
-
עכשיו נראה לי שעכשיו אני מבין
פשוט לא שייך לעשות aggregate אם אין group (אולי אפשר אבל אין לזה משמעות)וחוץ מזה השאילתא
SELECT * FROM info GROUP BY user WHERE id > 10000;
לא תעבוד, כי אי אפשר לעשות WHERE אחרי הGROUP.
אבל השאילתא
SELECT * FROM info GROUP BY user HAVING id > 10000;
תעבוד.
וכנ"לSELECT * FROM info HAVING id > 10000;
אז השאלה שלי עכשיו, למה לא להשתמש תמיד בHAVING ?
@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 אין משמעות
-
אני צריך לתקן קצת במאמר שלי. כתבתי שאחרי קיבוץ אי אפשר להזכיר ערך של שורה ספציפית רק ערך של פונקציה שמסכמת באיזשהו צורה את כל השורות המקופלות בשורה זו. זה לא לגמרי נכון, כי אפשר להזכיר את הערך של העמודה שלפיה עשית את הקיבוץ מכיון שהערך שווה לכל השורות המקובצות. (בחלק מהמנועים אפשר להזכיר ערכים של עמודות אחרות אבל אין לזה משמעות ברורה).
אני לא יודע אם הדבר הזה בלבל אותךמשמע שזה משמש גם בשביל GROUP BY וגם בשביל שאר הערכים שמתקבלים מתוך פונקציה.
אני לא בטוח שאני מבין לאיזה שני דברים אתה מתכוון.
האם זה אומר שיש אופציה שישתמשו בHAVING בלי GROUP BY?
אפשר, אבל זה עושה קיפול מובן (implicit) של כל השורות לשורה אחת
-
@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 נראה שאתה צודק.
http://sqlfiddle.com/#!9/5ccdef/6/0
זו התנהגות לא סטנדרטית של mysql ועדיף לא להשתמש בה. -
עכשיו נראה לי שעכשיו אני מבין
פשוט לא שייך לעשות aggregate אם אין group (אולי אפשר אבל אין לזה משמעות)וחוץ מזה השאילתא
SELECT * FROM info GROUP BY user WHERE id > 10000;
לא תעבוד, כי אי אפשר לעשות WHERE אחרי הGROUP.
אבל השאילתא
SELECT * FROM info GROUP BY user HAVING id > 10000;
תעבוד.
וכנ"לSELECT * FROM info HAVING id > 10000;
אז השאלה שלי עכשיו, למה לא להשתמש תמיד בHAVING ?
@nigun אמר בהאנטומיה של שאילתת SQL- תגובות:
אז השאלה שלי עכשיו, למה לא להשתמש תמיד בHAVING ?
מבחינת יעילות, לענ"ד אין להשתמש ב HAVING אם אפשר להשתמש ב- WHERE, מפני שה-WHERE הוא מסנן מוקדם ברמת השורה, ומתבצע לפני הקיבוץ, וכך הקיבוץ מתבצע על קבוצה קטנה יותר (תוצאת ה-WHERE) לעומת זאת ה-HAVING הוא מסנן מאוחר ברמת קבוצה, ויתבצע על כל הרשומות.
-
@nigun אמר בהאנטומיה של שאילתת SQL- תגובות:
אז השאלה שלי עכשיו, למה לא להשתמש תמיד בHAVING ?
מבחינת יעילות, לענ"ד אין להשתמש ב HAVING אם אפשר להשתמש ב- WHERE, מפני שה-WHERE הוא מסנן מוקדם ברמת השורה, ומתבצע לפני הקיבוץ, וכך הקיבוץ מתבצע על קבוצה קטנה יותר (תוצאת ה-WHERE) לעומת זאת ה-HAVING הוא מסנן מאוחר ברמת קבוצה, ויתבצע על כל הרשומות.
-
@yossiz
למה לא סטנדרתית
בתיעוד של SQL שהבאתי למעלה כתוב
When GROUP BY is not used, HAVING behaves like a WHERE clause -
@nigun זה היה נכון ב-SQL Server 2005, בתיעוד של הגירסה העדכנית כתוב כמו שאני כתבתי:
When GROUP BY is not used, there is an implicit single, aggregated group.
-
@yossiz
אז איך יראה התוצאה בSQL Server 2019
(לא הבנתי מה זה implicit).אני מנחש שהם שינו את זה בגלל שזה גורם לחוסר אחידות בשימוש של HAVING
וכך גם שאר המנועים, אבל MYSQL החליטו להשאיר את זה משום מה. -
@yossiz
אז איך יראה התוצאה בSQL Server 2019
(לא הבנתי מה זה implicit).אני מנחש שהם שינו את זה בגלל שזה גורם לחוסר אחידות בשימוש של HAVING
וכך גם שאר המנועים, אבל MYSQL החליטו להשאיר את זה משום מה. -
@nigun אמר בהאנטומיה של שאילתת SQL- תגובות:
אז איך יראה התוצאה בSQL Server 2019
לא תראה תוצאה כי השאילתה לא חוקית כי אסור להזכיר עמודה שהוא לא חלק מה-group by אם לא על ידי פונקצית aggregation.
דוד תרגם את המילה implicit כ"משתמע" או "מרומז" -
@nigun אמר בהאנטומיה של שאילתת SQL- תגובות:
אז איך יראה התוצאה בSQL Server 2019
לא תראה תוצאה כי השאילתה לא חוקית כי אסור להזכיר עמודה שהוא לא חלק מה-group by אם לא על ידי פונקצית aggregation.
דוד תרגם את המילה implicit כ"משתמע" או "מרומז"@yossiz
יצאתי מבולבל@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
לא תראה תוצאה כי השאילתה לא חוקית כי אסור להזכיר עמודה שהוא לא חלק מה-group by אם לא על ידי פונקצית aggregation.
@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
אפשר, אבל זה עושה קיפול מובן (implicit) של כל השורות לשורה אחת
יש תוצאה או לא?
ואיך נכנס לכאן implicit? -
@yossiz
יצאתי מבולבל@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
לא תראה תוצאה כי השאילתה לא חוקית כי אסור להזכיר עמודה שהוא לא חלק מה-group by אם לא על ידי פונקצית aggregation.
@yossiz אמר בהאנטומיה של שאילתת SQL- תגובות:
אפשר, אבל זה עושה קיפול מובן (implicit) של כל השורות לשורה אחת
יש תוצאה או לא?
ואיך נכנס לכאן implicit?@nigun אתה צודק, סתרתי את עצמי. כי לא בדקתי את ההתנהגות של כל המנועים וניסיתי לנחש מה יהיה ההתנהגות של mysql, הניחוש לא יצא כל כך מוצלח
יש תוצאה או לא?
אין.
ואיך נכנס לכאן implicit?
כי לא עשית קיבוץ בפירוש על ידי
GROUP BY
אז הקיבוץ הוא "לא מפורש" או "מרומז" או "משתמע" או איך שתקרא לזה... מזה שעשית סינון על התוצאה של הקיבוץ על ידיHAVING
.