האם יש לSQL פונקציה להכפלת כל השדות?

innerJoin

New member
האם יש לSQL פונקציה להכפלת כל השדות?

שלום אני מחפשת משהו מקביל ל SUM, אבל כדי לקבל מכפלה. לדוג', אם הטבלה שלי מכילה שלוש שורות: 3 4 5 אני צריכה לקבל 3*4*5, כלומר - 60. יש דבר כזה בשאילת SQL פשוטה, או שאני צריכה לכתוב קוד? אני צריכה את זה group by עמודה אחרת, אז הכי קל זה בשאילתה, השאלה היא אם קיים דבר כזה ב SQL SERVER 2008 ?
 

גרי רשף

New member
אין, אבל יש פטנט..

הפעילי על השדה Log, סכמי בעזרת Sum, מצאי את האנטי-לוג של הסכום בעזרת Exp. בערך כך:
Select ID, Exp(Sum(Log(MyFld))) From MyTbl Group By ID;​
כמובן שתהיה בעייה עם מספרים שליליים ואפס.
 

pitoach

New member
מרשים
מי בכלל זוכר שיש דבר כזה במתמטיקה

כמו LOG
 

גרי רשף

New member
שמע- נרדמת בשמירה!

התפקיד שלי כאן בפורום למצוא כל מיני פתרונות מסובכים ב-TSQL, ושלך- לומר שהכי טוב עם CLR..
 

zalomon

New member
הערה: השיטה יפה אך

מתקבלות בה שגיאות דיוק, משום שעוברים לחישוב בשברים ובפרט במספרים אי רציונאליים אותם לא ניתן לבטא במדויק. לכן התוצאה של חישוב פשוט של 2*3*4 יכולה לצאת קצת שונה מ-24. על כפל של שלושה מספרים זה שניח - אפשר לעשות ROUND. על כפל של 100,000 מספרים מתוך טבלה, נניח, הזליגה יכולה להיות משמעותית.
 

כלליים

New member
עדיין אפשר

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

innerJoin

New member
עד כמה זה משמעותי?

אני צריכה בסופו של דבר לעגל ל-2 ספרות אחרי הנקודה. אין לי יותר מ-10 שורות לכל ID. אבל יש עשרות אלפי ID-ים, כך שלבדוק את כולם זה לא מעשי, והתוכן של הטבלה יכול גם להשתנות בהמשך (לא יהיו אפסים ומספרים שליליים בוודאות, אבל המספרים לא שלמים, - בין 0.1 ל 2). בדקתי כמה בודדים ובינתיים הכל בסדר. עד כמה האי דיוק משמעותי לי? התכוונת לעשות ROUND לפני ה SUM? זה כבר ממש מעוות את התוצאות. אולי לא הבנתי אותך?
Exp(Sum(Round(Log(x))) ???​
 

כלליים

New member
אתה צודק!

שכחתי שכל LOG מחזיר שבר, וROUND ישבש הכל. בענין הדיוק הכולל, אינני יודע.
 

pitoach

New member
לא צריכה להיות בעיה של דיוק אם עובדים בסוג

נכון של טורים בעקרון. כמובן שיכול להיות שיבוש כזה או אחר בלוגישקה שהוצעה כאן, אבל צריך לקחת את זה בחשבון של האפיון ולהחליט תמיד אם האפיון מתאים לפתרון המסויים שהוצע. אם רוצים פתרון ישיר מדוייק אז ניתן לבצע פשוט להגדיר פונקציה שמקבלת בהפעלה שלה נתון של הטור או הטורים לפיהם רוצים לבצע את הקיבוץ GROUP BY. ופונקציה זו בצע בחירה (שאילתה פשוטה) של כל הנתונים תוך שימוש בסינון של השדות שנבחרו כך שיהיו שווים לזה של השדה הנוכחי (זו למעשה המשמעות של GROUP BY... בודקים מה הערך של הטור ברשומה הנוכחית ואז בוחרים את כל הרשומות עם אותו ערך). לוגיקה זו תיתן תמיד פתרון מדוייק (אני בטח הייתי עובד דרך כזו כברירת מחדל לבעיה רק שבמקום פונקציה הייתי עובד עם SP כדי לאפשר קימפול טוב של התוצאות וחיסכון בפעולות כפולות) אבל... יש גורמים כמו מיטוב שאילתה למשל והכל שאלה של רווח מול הפסד. אני מאוד ממליץ לקרוא את 2 הקישורים הבאים לעומק ופשוט לבחור את סוג הנתונים המתאים לכם לפי הדיוק שרוצים. לא תמיד כדאי לרוץ לברירת המחדל ובטח לא להיסתמך על בדיקות חסרות בסיס כי הן בודקות את ברירת המחדל בלבד אלא לבדוק את ההתאמה המיטבית לאפיון. כך למשל בסוג של דצימלי תוכלו לקבוע לבד מה הדיוק שרוצים (עד הרמה שמאופשרת כמובן בסוג זה) ובסוגים אחרים פשוט רמת הדיוק נקבעת לפי הסוג http://msdn.microsoft.com/en-us/library/ms173773.aspx http://msdn.microsoft.com/en-us/library/aa258832(v=sql.80).aspx
 

כלליים

New member
למה זה תלוי בסוג הנתונים של השדה?

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

pitoach

New member
הסבר

אם בדרך בפעולה מתמטית אתה מעל 10 או 1 אחרי הנקודה התוצאה הסופית מושפעת. סוג השדה יקבע את החישוב באמצע מפני שהשרת בוחר סוג בצורה של ברירת המחדל ואנחנו יכולים לעקוף את זה. כשאני מדבר על סוג הטור אני מדבר על סוג הנתון המחושב ולא סוג הנתון המקורי שלא מעניין כשמבצעים המרה למשל לסוג אחר בתחילת התהליך. 1.1+2.1+3.4 = 6.6 1.1.4+2.1.4+3.4.4 = 6.72 עתה אפילו נאם נעגל תוצאה סופית ל 1 אחרי הנקודה נקבל תוצאות שונות כי בחישובי הביניים נעשו עיגולים שונים ולכן בכל נקודה בחישוב בוצע אי דיוק כלשהו וביחד כל האי דיוקים יכולים לפעול ולחזק זה את זה לאי דיוק גדול אחד (או לבטל זה את זה לפעמים) * אני מקווה שלא טעיתי חישוב החשבוני
* מכיוון שמדובר באקספוננט הרי שיכול להיות שבערכים גדולים העיגול ישפיע (לא בדקתי ובכל מקרה כל מה זה לא מוריד מהרעיון הנחמד של שימוש בלוג על מנת לבצע פעלת חיבור במקום פעולת כפל
)
 

zalomon

New member
מבדיקה שעשיתי עכשיו

ב-mysql על טבלה עם 100,000 שורות כשהערכים הם 2, 0.5 חוזרים על עצמם 50,000 פעמים, התוצאה, למרבה השמחה, היא בדיוק 1. אני עדיין חושש שזה לא מחייב שתמיד יצא כל כך יפה.
 

גרי רשף

New member
לדעתי זה פחות קריטי ממה שזה נראה

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

zalomon

New member
אם אכן מדובר בחישובים כספיים

אזי ממש אין להשתמש ב-log. הדרישות מאוד מחמירות לגבי דיוק חישובים כלכליים, ובכלל עבודה ב-floating point אינה רצויה. ב-MySQL הטיפוס המתאים הוא DECIMAL, ולא ניתן יהיה להתמש בטריק שלעיל. באמת מוזר שאין כזו פונקציית אגרגציה, לא?
 

גרי רשף

New member
מה הכוונה ב"דרישות מחמירות"?

נכון- אני לא יכול להציג דוח כספי בו כתוב ש-
10,000.00+10,000.00=20,000.01​
ולהיתמם שאגורה אחת מתוך 20,000 ש"ח זה זניח.. לעומת זאת- אם שואלים אותי כמה שווים 10,000 ש"ח מלפני שלוש שנים בהנחה שהמדד עלה בשלוש השנים האחרונות ב-1.5%, 2.1%, 0.7% בהתאמה אזי:
10,000*1.015*1.021*1.007=10435.69205​
ואוכל להציג את זה בתור 10,436 או 10,435.69 וכו'; אני אהיה חייב לעגל, ואם החישוב יפספס קצת ובמקום להחזיר לי 10435.69205 יחזיר לי 10435.69208 (שזו סטייה גדולה בהרבה מזו של ה-Log הנ"ל) - זה באמת לא משנה הרבה.
 

zalomon

New member
אני מאמין (למרות שאני לא בתחום)

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

גרי רשף

New member
אם כבר Round- אז על כל הביטוי

למה אתם צריכים את זה? כלומר- המספרים בין 0.1 ל-2 מה הם מייצגים? מה מבטאת המכפלה שלהם? אלו בוודאי לא הסתברויות, אז אני מנחש שמדובר בעליית המדד לתקופה או במשהו דומה מתחום הכלכלה.
 
למעלה