יום רביעי, 6 ביוני 2012

ספירת הזמנות במחיר מינימום לפריט

בפוסט באתר dwh.co.il הועלתה השאלה הבאה:
כיצד להציג טבלה ובה עבור כל מוצר, ספירה של ההזמנות שבהן אותו מוצר נמכר במחיר הנמוך ביותר?
למשל: מוצר "כובע מצחיה" נמכר ב-92 הזמנות במחיר 12 ש"ח, ב-36 הזמנות במחיר 14 ש"ח, ואילו ב-45 הזמנות במחיר 13 ש"ח. הטבלה צריכה להציג עבור מוצר זה את הערך 92, כי זוהי כמות ההזמנות שבהן נמכר המוצר במחיר הנמוך ביותר (12 ש"ח).
הצורך הוא שהחישוב יהיה דינמי, ולכן חישוב בסקריפט איננו מתאים.
הנטייה הטבעית היא לנסות להשתמש בפונקציית Aggr אשר יודעת להתחשב גם באגרגציה של הפריט הנוכחי וגם באגרגציה של פריטים מקבילים. ואולם במקרה זה פונקציה זו לא תועיל, כיוון שאנו לא מחפשים את המחיר אלא את מספר ההזמנות של מחיר זה.
ניסיון לחשוב "מחוץ לקופסה" הביא אותי להפוך את הערכים המרובים למחרוזת טקסט, ובמישור זה להתמודד עם הבעיה.
כמובן, קבעתי את Product בתור מימד, ולאחר מכן הרכבתי את הביטוי אשר יתייחס אל Product.
ראשית, הביטוי צריך להכיר את כלל המחירים שבהם נמכר המוצר בכל ההזמנות (כולל מופעים כפולים בהזמנות שונות). זאת ניתן לבצע בעזרת הפונקציה Concat, אשר יודעת לשרשר ערכים מרובים למחרוזת טקסט בודדת. ולכן, הגדרתי תחילה בתור ביטוי:
Concat(PriceInOrder,'_')
השימוש בקו התחתון הוא כדי שתהיה הפרדה בין כל מחיר ומחיר.
מול המחרוזת הארוכה שהיא תוצאת הביטוי הנ"ל, יש להעמיד את מחיר המינימום שבו נמכר פריט זה, כלומר הביטוי
Min(PriceInOrder)
כעת, מה שנשאר הוא לספור כמה פעמים מופיע הביטוי השני (מחיר המינימום) בתוך הביטוי הראשון (כלל המחירים)!
אם-כן הביטוי המלא הוא:
SubstringCount(Concat(PriceInOrder,'_') & '_', min(PriceInOrder) & '_')
יש לשים לב שבחלק של מחיר המינימום הוספנו קו תחתון, כיוון שאנו רוצים לוודא שישנה התאמה מלאה של המספרים (ולא שתימצא התאמה בין 12 ל-122, למשל). גם לחלק של ה-Concat הוספנו בסופו קו תחתון, וזאת מכיוון שאנו רוצים שהחיפוש יתבצע גם על האבר האחרון ששורשר ב-Concat (והפונקציה עצמה אינה מוסיפה את ה-Delimiter בסוף האיברים אלא רק ביניהם).

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


אין תגובות:

הוסף רשומת תגובה