Imagine tickets de suporte técnico transferidos entre departamentos. Queremos saber o que é o departamento no final do dia para cada ticket para cada dia em que o ticket estiver aberto. A tabela contém o último departamento para cada ticket, para cada dia em que está aberto, no qual há uma alteração no departamento (incluindo uma linha para a data em que o ticket foi aberto inicialmente e a data em que foi fechado). A tabela de dados fica assim:
CREATE TABLE TicketAssigment (
TicketId INT NOT NULL,
AssignedDate DATE NOT NULL,
DepartmentId INT NOT NULL);
O que eu preciso é preencher as datas ausentes para cada TicketId, usando o DepartmentId da linha TicketAssigment anterior, ordenada por Data.
Se eu tiver linhas TicketAssigment como esta:
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
Eu quero esta saída:
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
Parece que pode estar perto do que eu preciso, mas não tive paciência para deixá-lo terminar, e o custo estimado do plano tem 6 dígitos:
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;
Suspeito que exista uma maneira de fazer isso usando o LAG e uma moldura de janela, mas ainda não o descobri. Qual é a maneira mais eficiente de atender aos requisitos?