Pergunta

Vamos dizer, eu tenho duas tabelas, uma para os registros de objetos e um para os registos de actividade sobre esses objetos.

eu estou inserindo um novo recorde nesta tabela atividade cada vez que um objeto é inserido ou atualizado.

para contá-la em uma maneira simples, suponha que eu tenho quatro campos na tabela de atividade; objectId, tipo, status e data.

quando um objeto está prestes a ser atualizada, eu estou planejando para obter o último estado para o objeto e olhar para as mudanças. Se há uma diferença entre o valor de atualização e o valor anterior, eu vou definir o valor por uma nova entrada, caso contrário eu vou defini-lo nulo. assim, por exemplo, em um processo de atualização, o usuário só muda o valor do status do objeto, mas deixa o valor do tipo de como o mesmo, então eu vou inserir uma nova linha com um valor nulo para o tipo e um novo valor para o estado.

SELECT * FROM Activity;

oid   type   status   date
-----------------------------------------
1     0      1        2009.03.05 17:58:07
1     null   2        2009.03.06 07:00:00
1     1      null     2009.03.07 20:18:07
1     3      null     2009.03.08 07:00:00

então eu tenho que criar uma visão me diz que o estado atual do meu objeto como,

SELECT * FROM ObjectStateView Where oid = 1;

oid   type   status   date
-----------------------------------------
1     3      2        2009.03.08 07:00:00

Como faço para conseguir isso _?

Foi útil?

Solução

data Supondo que pode ser usado para encontrar último disco:

CREATE VIEW foo
AS
    SELECT
        A.oid,
        (SELECT TOP 1 type FROM Activity At WHERE At.OID = A.oid AND At.Date <= MAX(A.date) AND type IS NOT NULL),
        (SELECT TOP 1 status FROM Activity Ast WHERE Ast.OID = A.oid AND Ast.Date <= MAX(A.date) AND status IS NOT NULL),
        MAX(A.date) AS date
    FROM
        Activity A
GO

Editar: se você quiser um JOIN (não testado)

CREATE VIEW foo
AS
    SELECT TOP 1
        A.oid,
        At.type,
        Ast.status,
        A.date
    FROM
        Activity A
        LEFT JOIN
        (SELECT TOP 1 oid, date, type FROM Activity WHERE type IS NOT NULL ORDER BY date DESC) At ON A.OID = At.oid
        LEFT JOIN
        (SELECT TOP 1 oid, date, status FROM Activity WHERE status IS NOT NULL ORDER BY date DESC) Ast ON A.OID = Ast.oid
    ORDER BY date DESC
GO

Deveria ter acrescentado isso antes:

Ele será ampliado exponencialmente porque você tem que tocar a mesa 11 vezes diferentes.

A melhor solução seria a de manter uma tabela de "atual" e mantê-lo por meio de um gatilho em actividade.

Outras dicas

Você já pensou em usar a função MAX ?

select oid, type, status, MAX(date) as max_date 
from ObjectStateView 
where oid = 1

Na verdade, não sei por que você iria querer os nulos lá. Você pode acompanhar o que mudou entre entradas, comparando a mais recente entrada para o anterior. Em seguida, o estado atual do objeto é a mais recente entrada na tabela. Você pode determinar se um objeto foi alterado através da criação de um hash das partes do objeto que você deseja acompanhar as mudanças para e armazenar isso como uma coluna extra.

valores históricos:

Uma vez que você acompanhar as mudanças, você pode querer ver o status do objeto historicamente:

SELECT      a.oid,
            a.date,
            a_type.type,
            a_status.status
FROM        Activity a
LEFT JOIN   Activity a_type
        ON  a_type.oid = a.oid
        AND a_type.date = (SELECT TOP 1 date FROM Activity WHERE oid = a.oid AND date <= a.date AND type IS NOT NULL ORDER BY date DESC)
LEFT JOIN   Activity a_status
        ON  a_status.oid = a.oid
        AND a_status.date = (SELECT TOP 1 date FROM Activity where oid = a.oid AND date <= a.date AND status IS NOT NULL ORDER BY date DESC)

que irá retornar:

oid         date       type        status
----------- ---------- ----------- -----------
1           2009-03-05 0           1
1           2009-03-06 0           2
1           2009-03-07 1           2
1           2009-03-08 3           2

consideração Performance:

Por outro lado, se você tem mais do que apenas alguns campos, e a tabela é grande, o desempenho poderia se tornar um problema. Neste caso, eu faria sentido também para loja / armazenar em cache os valores inteiros em outra tabela MyDataHistory , que contêm dados como no quadro mostrado acima. Em seguida, selecionando a versão atual (mais recente) é trivial usando uma exibição SQL filtrando a última linha (linha 1 apenas) por data oid e.

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