sql משהו מסובך
-
שלום לכולם.
לא מצאתי כותרת מתאימה לשאלה, ולכן פשוט אציג את הקוד וזהו. זאת שאלה די מורכבת ב SQL למעוניינים באתגר.יש לנו מידע על עמדות משרד מאויישות, ומידע על שיחות בטבלה שמגיעה ממרכזיית אסטריסק, התפקיד שלי כעת זה לשייך כל שיחה לפקיד שאייש את העמדה. כל עוד בשעת השיחה העמדה היתה מאויישת הכל בסדר. הבעיה מתחילה כשהעמדה לא מאויישת (שזה בדרך כלל שיחות נכנסות שלא נענו או תא קולי) ולפי ההוראות של הבוס, השיחה שייכת לאחרון שאייש את העמדה. כתבתי SQL לדוגמא (אפשר פשוט להעתיק ולהדביק) והתוצאה כמובן לא נכונה.
declare @Working table (StartTime datetime, EndTime datetime,OfficePosition int, UserID int); declare @Calls table (StartTime datetime,EndTime datetime , OfficePosition int,UserID int); -- טבלת שעות עבודה insert into @Working values ('01-01-2015 08:00:00','01-01-2015 14:00:00',1,10), ('01-01-2015 08:00:00','01-01-2015 14:00:00',2,11), ('01-01-2015 19:00:00','01-01-2015 22:00:00',1,12); --טבלת שיחות כל מה שהמרכזייה יודעת זה שעת התחלה וסיום ועמדת המשרד שבה בוצעה השיחה insert into @Calls(StartTime ,EndTime,OfficePosition) values ('01-01-2015 08:30:00','01-01-2015 08:35:00',1), ('01-01-2015 22:30:00','01-01-2015 22:31:00',1); -- מעדכן את העובד שביצע שיחות כאשר ידוע מי אייש את העמדה בשעת השיחה update c set c.UserID = w.UserID from @Calls c inner join @Working w on c.OfficePosition=w.OfficePosition and (c.StartTime between w.StartTime and w.EndTime); --מעדכן שיחות שבוצעו כאשר העמדה לא הייתה מאויישת, ומשייך את השיחות לאחרון שאייש את העמדה update c set c.UserID = w.UserID from @Calls c inner join @Working w on c.OfficePosition=w.OfficePosition and not (c.StartTime between w.StartTime and w.EndTime) and c.UserID is null; select * from @Calls;
אני יודע שתמיד אפשר לעשות טבלה זמנית בשביל לדעת מי האחרון שאייש כל עמדה, אבל כאן יש נושא של אופטימיזציה, כי הפרוצדורה שמעדכנת את המידע צריכה לרוץ כמעט כל חצי דקה בממוצע, ואם יש לנו עשרות אלפי רשומות הן של שיחות והן של שעות עבודה ואיוש עמדות, מובן שזה לא מוצלח, אני צריך לעשות משהו הכי אלגנטי שיטריח כמה שפחות את הSQL.
תודה לכולם.
פורסם במקור בפורום CODE613 ב15/03/2015 09:37 (+02:00)
-
--מעדכן שיחות שבוצעו כאשר העמדה לא הייתה מאויישת, ומשייך את השיחות לאחרון שאייש את העמדה update c set c.UserID = w.UserID from @Calls c CROSS APPLY (SELECT TOP 1 UserID FROM @Working w WHERE w.OfficePosition = c.OfficePosition AND c.StartTime > w.EndTime ORDER BY w.EndTime DESC) AS w WHERE c.UserID is null;
פורסם במקור בפורום CODE613 ב15/03/2015 14:15 (+02:00)