Pregunta

digamos, tengo dos tablas, una para registros de objetos y otra para registros de actividad sobre estos objetos.

estoy insertando un nuevo registro en esta tabla de actividades cada vez que se inserta o actualiza un objeto.

para decirlo de forma sencilla, suponga que tengo cuatro campos en la tabla de actividades; ID de objeto, tipo, estado y fecha.

cuando un objeto está a punto de actualizarse, estoy planeando obtener el último estado para el objeto y buscar los cambios. Si hay una diferencia entre el valor de actualización y el valor anterior, estableceré el valor con una nueva entrada, de lo contrario, lo estableceré en nulo. así, por ejemplo, en un proceso de actualización, el usuario solo cambia el valor de estado del objeto, pero deja el valor de tipo como el mismo, por lo que insertaré una nueva fila con un valor nulo para el tipo y un nuevo valor para el 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

así que tengo que crear una vista que me diga el estado actual de mi objeto,

SELECT * FROM ObjectStateView Where oid = 1;

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

¿Cómo logro esto_?

¿Fue útil?

Solución

Suponiendo que la fecha se puede usar para encontrar el último registro:

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: si quieres un JOIN (sin probar)

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

Debería haber agregado esto antes:

Se escalará exponencialmente porque debe tocar la mesa 11 veces diferentes.

Una mejor solución sería mantener una " actual " Mesa y manténgala a través de un desencadenante de actividad.

Otros consejos

¿Ha considerado usar la función MAX ?

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

No estoy seguro de por qué querrías los nulos allí. Puede hacer un seguimiento de lo que ha cambiado entre las entradas comparando la última entrada con la anterior. Entonces, el estado actual del objeto es la última entrada en la tabla. Puede determinar si un objeto ha cambiado al crear un hash de las partes del objeto que desea rastrear los cambios y almacenarlo como una columna adicional.

Valores históricos:

Dado que realiza un seguimiento de los cambios, es posible que desee ver el estado del objeto históricamente:

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 volverá:

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

Consideración de rendimiento:

Por otro lado, si tiene más de unos pocos campos y la tabla es grande, el rendimiento se convertiría en un problema. En este caso, también tendría sentido almacenar / almacenar en caché los valores completos en otra tabla MyDataHistory , que contendría datos como en la tabla que se muestra arriba. Luego, seleccionar la versión actual (la última) es trivial utilizando una vista de SQL que filtra la última fila (solo 1 fila) por oid y fecha.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top