Зображуйте квитки довідкової служби, які передаються між відділами. Ми хочемо знати, що таке відділення в кінці дня для кожного квитка на кожен день, коли квиток відкритий. У таблиці міститься останній відділ для кожного квитка на кожен день, він відкритий, на якому відбувається зміна у відділі (включаючи рядок щодо дати первинного відкриття квитка та дати його закриття). Таблиця даних виглядає приблизно так:
CREATE TABLE TicketAssigment (
TicketId INT NOT NULL,
AssignedDate DATE NOT NULL,
DepartmentId INT NOT NULL);
Що мені потрібно - це заповнити будь-які пропущені дати для кожного TicketId, використовуючи DepartmentId з попереднього ряду TicketAssigment, упорядкований за датою.
Якщо у мене є такі рядки TicketAssigment:
1, '1/1/2016', 123 -- Opened
1, '1,4,2016', 456 -- Transferred and closed
2, '1/1/2016', 25 -- Opened
2, '1/2/2016', 52 -- Transferred
2, '1/4/2016', 25 -- Transferred and closed
Я хочу цього виходу:
1, '1/1/2016', 123
1, '1/2/2016', 123
1, '1/3/2016', 123
1, '1/4/2016', 456
2, '1/1/2016', 25
2, '1/2/2016', 52
2, '1/3/2016', 52
2, '1/4/2016', 25
Схоже, це може бути близьким до того, що мені потрібно, але я не мав терпіння дозволити його закінчити, і орієнтовна вартість плану має 6 цифр:
SELECT l.TicketId, c.Date, MIN(l.DepartmentId)
FROM dbo.Calendar c
OUTER APPLY (SELECT TOP 1 TicketId, DepartmentId FROM TicketAssigment WHERE AssignedDate <= c.Date ORDER BY AssignedDate DESC) l
WHERE c.Date <= (SELECT MAX(AssignedDate) FROM TicketAssigment)
GROUP BY l.TicketId, c.Date
ORDER BY l.TicketId, c.Date;
Я підозрюю, що є спосіб зробити це за допомогою LAG та віконної рами, але я не зовсім зрозумів це. Який більш ефективний спосіб задоволення вимоги?