O SQL Server melhor maneira para calcular datediff entre a linha atual e linha seguinte?

StackOverflow https://stackoverflow.com/questions/52430

  •  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.

Foi útil?

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.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top