Domanda

diciamo, ho due tabelle, una per i record degli oggetti e una per i record delle attività su questi oggetti.

Sto inserendo un nuovo record in questa tabella di attività ogni volta che un oggetto viene inserito o aggiornato.

per dirlo in modo semplice, supponiamo che io abbia quattro campi nella tabella delle attività; objectId, tipo, stato e data.

quando un oggetto sta per essere aggiornato, sto pianificando di ottenere l'ultimo stato dell'oggetto e cercare le modifiche. se c'è una differenza tra il valore di aggiornamento e il valore precedente, imposterò il valore con un nuovo input, altrimenti lo imposterò su null. quindi ad esempio in un processo di aggiornamento, l'utente modifica solo il valore dello stato dell'oggetto ma lascia il valore del tipo uguale, quindi inserirò una nuova riga con un valore nullo per il tipo e un nuovo valore per lo stato.

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

quindi devo creare una vista che mi dice lo stato corrente del mio oggetto come,

SELECT * FROM ObjectStateView Where oid = 1;

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

come ottengo questo_?

È stato utile?

Soluzione

Supponendo che la data possa essere utilizzata per trovare l'ultimo record:

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

Modifica: se vuoi un JOIN (non testato)

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

Avrei dovuto aggiungerlo prima:

Si ridimensionerà in modo esponenziale perché devi toccare la tabella 11 volte diverse.

Una soluzione migliore sarebbe quella di mantenere un "attuale" tabella e mantenerlo tramite un trigger sull'attività.

Altri suggerimenti

Hai preso in considerazione l'utilizzo della MAX ?

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

Non sono proprio sicuro del motivo per cui vorresti inserire i null. Puoi tenere traccia di ciò che è cambiato tra gli input confrontando l'ultima voce con la precedente. Quindi lo stato corrente dell'oggetto è l'ultima voce nella tabella. Puoi determinare se un oggetto è cambiato creando un hash delle parti dell'oggetto su cui desideri tenere traccia delle modifiche e memorizzandolo come colonna aggiuntiva.

Valori storici:

Dato che segui le modifiche, potresti voler vedere lo stato dell'oggetto storicamente:

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)

che restituirà:

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

Considerazioni sul rendimento:

D'altra parte, se hai più di un paio di campi e la tabella è grande, le prestazioni diventerebbero un problema. In questo caso avrei senso anche archiviare / memorizzare nella cache tutti i valori in un'altra tabella MyDataHistory , che conterrebbe dati come nella tabella mostrata sopra. Quindi selezionare la versione corrente (più recente) è banale usando una vista SQL che filtra l'ultima riga (solo 1 riga) per oid e data.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top