O SQL Server melhor maneira para calcular datediff entre a linha atual e linha seguinte?
-
09-06-2019 - |
Pergunta
Eu tenho a seguinte áspero estrutura:
Object -> Object Revisions -> Data
Os Dados podem ser compartilhados entre vários Objetos.
O que eu estou tentando fazer é limpar antigo Objeto de Revisões.Eu quero manter o primeiro, ativo, e de um spread de revisões, de modo que a última alteração para um período de tempo é mantido.Os Dados poderão ser mudado muito ao longo do curso de 2 dias, em seguida, deixado sozinho por meses, então eu quero manter a última revisão antes de as mudanças começaram e o final de alteração do novo conjunto.
Atualmente estou usando um cursor e a tabela temporária para armazenar o id e data de entre as alterações para que eu possa selecionar o pendurando as frutas de baixo para livrar-se de.Isso significa usar o @LastID, @LastDate, atualizações e inserções para a tabela temporária, etc...
Existe uma maneira mais fácil/melhor para calcular a data diferença entre a linha atual e a linha seguinte na minha primeira conjunto de resultados sem a utilização de um cursor e a tabela temporária?
Eu estou no sql server 2000, mas estaria interessado em quaisquer novos recursos, de 2005, de 2008, que poderia ajudar com isso também.
Solução
Se a coluna de identidade é sequencial você pode usar essa abordagem:
SELECT curr.*, DATEDIFF(MINUTE, prev.EventDateTime,curr.EventDateTime) Duration FROM DWLog curr join DWLog prev on prev.EventID = curr.EventID - 1
Outras dicas
Aqui está o exemplo de SQL.Se você tem uma coluna de Identidade, você pode usar isso em vez de "ActivityDate".
SELECT DATEDIFF(HOUR, prev.ActivityDate, curr.ActivityDate)
FROM MyTable curr
JOIN MyTable prev
ON prev.ObjectID = curr.ObjectID
WHERE prev.ActivityDate =
(SELECT MAX(maxtbl.ActivityDate)
FROM MyTable maxtbl
WHERE maxtbl.ObjectID = curr.ObjectID
AND maxtbl.ActivityDate < curr.ActivityDate)
Eu poderia remover "prev", mas ele não supondo que você precisa IDs para eliminar.
Hrmm, desafio interessante.Eu acho que você pode fazê-lo sem uma auto-associação, se você usar o novo para-2005 funcionalidade de tabela dinâmica.
Aqui está o que eu tenho até agora, eu queria dar um pouco mais de tempo antes de aceitar uma resposta.
DECLARE @IDs TABLE
(
ID int ,
DateBetween int
)
DECLARE @OID int
SET @OID = 6150
-- Grab the revisions, calc the datediff, and insert into temp table var.
INSERT @IDs
SELECT ID,
DATEDIFF(dd,
(SELECT MAX(ActiveDate)
FROM ObjectRevisionHistory
WHERE ObjectID=@OID AND
ActiveDate < ORH.ActiveDate), ActiveDate)
FROM ObjectRevisionHistory ORH
WHERE ObjectID=@OID
-- Hard set DateBetween for special case revisions to always keep
UPDATE @IDs SET DateBetween = 1000 WHERE ID=(SELECT MIN(ID) FROM @IDs)
UPDATE @IDs SET DateBetween = 1000 WHERE ID=(SELECT MAX(ID) FROM @IDs)
UPDATE @IDs SET DateBetween = 1000
WHERE ID=(SELECT ID
FROM ObjectRevisionHistory
WHERE ObjectID=@OID AND Active=1)
-- Select out IDs for however I need them
SELECT * FROM @IDs
SELECT * FROM @IDs WHERE DateBetween < 2
SELECT * FROM @IDs WHERE DateBetween > 2
Eu estou olhando para estender isso para que eu possa manter pelo máximo de tantas revisões, e pode desligar os mais velhos, mantendo o primeiro, o último e ativo.Deve ser bastante fácil através de uma selecção de topo e as cláusulas order by, hum...e jogando em ActiveDate para a tabela temporária.
Eu tenho o Pedro exemplo para o trabalho, mas teve que e modificado em uma subseleção.Eu brinquei com ambos e o rastreio de sql mostra a subseleção, fazendo menos lê.Mas ele faz o trabalho e eu vou votar nele até quando eu chegar em minha rep alta o suficiente.