יום שני, 28 במאי 2012

Sum מול Count ורשומות פיקטיביות עבור גרף קו


איך מחשבים בקליקוויו ספירה של הזמנות / לקוחות וכד'? לכאורה התשובה הפשוטה - Count, או בד"כ Count Distinct, על השדה המזהה. למשל:
 Count(DISTINCT OrderID)

אולם ישנה דרך נוספת לספור - באמצעות Sum. בסקריפט מוסיפים שדה Counter (בכל טבלה רלוונטית), ומכניסים לו את הערך 1. לאחר מכן הנוסחה לספירה תהיה:
Sum(OrderCounter)


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

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

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



ניתן לראות שהקו "מדלג" על חודש מרץ, במקום להציגו כ-0, עם ירידה ואז עלייה. לצופה בגרף נדמה כאילו בין פברואר לאפריל הייתה רק עלייה, מה שכמובן אינו נכון.
הפתרון הוא ליצור רשומה פיקטיבית עבור סוכן זה (ועבור כל סוכן / שדה אחר שבו זה נדרש), וב"סכום" ברשומה הפיקטיבית יהיה ערך 0 (יש לנקות את האפשרות Supress Zero-Values).
אבל ישנה בעיה: שדה "סוכן" נמצא בטבלת ההזמנות, ואילו שדה "סכום" נמצא בטבלת שורות הזמנה! לכן עלינו ליצור רשומה פיקטיבית גם בטבלת ההזמנות - בה יהיה הסוכן, וגם בטבלת שורות ההזמנה - בה יהיה הסכום. ואז, כדי לקשר בין הרשומות, נצטרך לתת להזמנה הפיקטיבית מזהה כלשהו. לא נוכל להשאיר את המזהה ריק.
הגרף יתוקן:

וכאן אנחנו חוזרים לנושא הראשון: כיצד נספור את ההזמנות? בטבלת ההזמנות יש כעת רשומות פיקטיביות, שאנו לא מעוניינים לספור, אבל יש להם מזהה. אם ננסה לספור באמצעות Count, הסכום יכלול גם את הרשומות הפיקטיביות!
שימוש ב-Sum לצורך הספירה, פותר את הבעיה. כאשר יוצרים בסקריפט את השדה OrderCounter ושותלים בו 1 בכל הזמנה, עושים זאת רק בהזמנות האמתיות ולא בהזמנות הפיקטיביות. כתוצאה מכך, ספירת  OrderCounter באמצעות Sum תספור רק את ההזמנות האמתיות.