Estou tentando obter uma lista de trabalhos e sua etapa concluída mais recentemente do banco de dados MSDB. Para um único trabalho, isso é bastante direto, algo como:
SELECT TOP 1 j.job_id, j.name, h.step_name, h.run_date, h.run_time, h.step_id
FROM msdb.dbo.sysjobs j
INNER JOIN msdb.dbo.sysjobhistory h ON j.job_id = h.job_id
WHERE j.name = 'my favorite job'
ORDER BY h.run_date DESC, h.run_time DESC, h.step_id DESC
Mas como posso obter uma lista de TODOS os trabalhos e sua etapa concluída mais recentemente?
Observe que este é SQL 2000, então não posso usar PARTITION OVER. Também não consigo fazer um SELECT MAX() porque não é um único campo RunDateTime, tenho que classificar de forma descendente por dois campos (OrderDay, OrderTime).
Edit: Provavelmente não é possível, mas eu adoraria poder fazer algo como:
SELECT j.job_id, ...
FROM msdb.dbo.sysjobs j
INNER JOIN (SELECT TOP 1 step_name, run_date, run_time, step_id
FROM msdb.dbo.sysjobhistory
WHERE job_id = j.job_id
ORDER BY run_date desc, run_time desc, step_id desc) as H
ou algo assim, mas não parece gostar de sintaxe assim...
Infelizmente, como pode haver empates (a penúltima etapa pode levar 0 segundos e, portanto, terminar "exatamente" ao mesmo tempo que a última etapa), isso não é muito bonito no SQL Server 2000. Em vez de calcular todos os datetime várias vezes, acho que a maneira mais fácil é colocá-lo em uma tabela #temp. Você pode considerar a criação de uma exibição permanente com a conversão de data e hora.
Acabei de perceber que sysjobhistory tem uma chave de identidade, "INSTANCE_ID". Não sei porque pensei que a mesa não tinha...
Encontrar o maior INSTANCE_ID para cada trabalho (excluindo a etapa 0) torna isso muito mais fácil e evita a tabela temporária:
Ainda tenho que colocar a conversão de data/hora lá, mas isso parece funcionar.