comment créer une vue mssql pour obtenir les dernières informations d'état

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

  •  03-07-2019
  •  | 
  •  

Question

Disons que j'ai deux tables, une pour les enregistrements d'objet et une pour les enregistrements d'activité concernant ces objets.

J'insère un nouvel enregistrement dans cette table d'activités chaque fois qu'un objet est inséré ou mis à jour.

Pour le dire simplement, supposons que j'ai quatre champs dans la table d’activités; objectId, type, statut et date.

lorsqu'un objet est sur le point d'être mis à jour, je prévois d'obtenir le dernier état pour l'objet et de rechercher les modifications. s'il y a une différence entre la valeur de mise à jour et la valeur précédente, je définirai la valeur avec une nouvelle entrée, sinon je la définirai comme nulle. Ainsi, par exemple, dans un processus de mise à jour, l'utilisateur modifie uniquement la valeur de statut de l'objet mais conserve la même valeur pour le type. Je vais donc insérer une nouvelle ligne avec une valeur null pour le type et une nouvelle valeur pour le statut.

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

donc je dois créer une vue me dit l'état actuel de mon objet comme,

SELECT * FROM ObjectStateView Where oid = 1;

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

comment puis-je atteindre ce _?

Était-ce utile?

La solution

En supposant que la date puisse être utilisée pour rechercher le dernier enregistrement:

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

Modifier: si vous voulez un JOIN (non testé)

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

aurait dû ajouter ceci plus tôt:

L’échelle sera exponentielle car vous devez toucher la table onze heures différentes.

Une meilleure solution serait de maintenir un "courant" et "courant". la table et la maintenir via un déclencheur d’activité.

Autres conseils

Avez-vous envisagé d'utiliser la fonction MAX ?

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

Vous ne savez pas vraiment pourquoi vous voudriez que les valeurs nulles soient présentes. Vous pouvez suivre ce qui a changé entre les entrées en comparant la dernière entrée à la précédente. L'état actuel de l'objet est alors la dernière entrée de la table. Vous pouvez déterminer si un objet a été modifié en créant un hachage des parties de l'objet pour lesquelles vous souhaitez suivre les modifications et en les stockant dans une colonne supplémentaire.

Valeurs historiques:

Puisque vous suivez les modifications, vous souhaiterez peut-être voir le statut de l'objet par le passé:

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)

qui retournera:

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

Considération sur les performances:

Par contre, si vous avez plus que quelques champs et que le tableau est volumineux, les performances deviennent un problème. Dans ce cas, il serait également judicieux de stocker / mettre en cache les valeurs entières dans une autre table MyDataHistory , qui contiendrait des données similaires à celles du tableau ci-dessus. Ensuite, la sélection de la version (la plus récente) actuelle est simple en utilisant une vue SQL filtrant la dernière ligne (une seule ligne) par oid et date.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top