2009-03-06 9 views
0

は、オブジェクトレコードとアクティビティレコードの2つのテーブルを持っています。最後の状態情報を取得するためのmssqlビューの作成方法

私はオブジェクトを挿入または更新するたびにこのアクティビティテーブルに新しいレコードを挿入します。

単純な方法でそれを伝えるために、私はアクティビティテーブルに4つのフィールドがあると仮定します。 objectId、タイプ、ステータス、および日付。

オブジェクトが更新されようとしているとき、私はオブジェクトの最後の状態を取得して変更を探します。更新値と前の値との間に差がある場合は、新しい入力で値を設定します。そうでない場合はnullに設定します。たとえば、更新プロセスでは、ユーザーはオブジェクトのステータス値を変更するだけですが、タイプ値は同じであるため、タイプのnull値とステータスの新しい値を持つ新しいローを挿入します。

 
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 

ので、私は

 
SELECT * FROM ObjectStateView Where oid = 1; 

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

どのように私はthis_を達成しない、私は私のようなオブジェクトの現在の状態指示するビューを作成する必要がありますか?

+0

タイプ、ステータス、および日付は厳密に単調である(常に増分します)。または、最新のレコードを作成するために日付を使用できますか?そうでない場合は、十分な情報がありません – gbn

+0

型とステータスの算術値は重要ではなく、実際にはいくつかの列挙型を参照します。しかし、はい、日付は常に増分されます – koraytaylan

答えて

0

と仮定すると、日付が最新のレコードを検索するために使用することができますが、

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 

が追加されているべきである(未テスト)に参加する場合は、この以前:

それがしますあなたはテーブル11に異なる時間に触れなければならないので指数関数的にスケールします。

より良い解決策は、「現在の」テーブルを維持し、アクティビティのトリガによって維持することです。

+0

ご返信ありがとうございます。 サブクエリではなく「結合」を使ってより良い方法があるのだろうか。それは私が推測するサーバーのためにそれを処理する方が速くなります。なぜなら、実際にアクティビティテーブルには約10個の状態フィールドがあるからです。 – koraytaylan

0

MAX機能の使用を検討しましたか?

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

アクティビティから行4を与えます...そしてビューはまだ存在しません – gbn

+0

私はkoraytaylanがクエリに興味があり、彼がビューを作成する方法を理解できると仮定しました。 – RuudKok

0

nullsが必要な理由はわかりません。最新のエントリを前のエントリと比較することによって、入力間で変更された内容を追跡できます。オブジェクトの現在の状態は、テーブルの最新のエントリです。変更を追跡するオブジェクトの部分のハッシュを作成し、それを追加の列として格納することによって、オブジェクトが変更されたかどうかを判断できます。

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 

編集:

0

履歴値:

変更を追跡しているので、あなたは歴史的にオブジェクトの状態を確認したいことがあります。

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) 

返される:

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 

パフォーマンス対価:

一方、複数のフィールドがあり、テーブルが大きい場合は、パフォーマンスが問題になります。この場合、別のテーブルに値全体を保存/キャッシュすることも意味があります。MyDataHistory、上記の表のようなデータが含まれています。その後、現在の(最新の)バージョンを選択するのは、最新の行(1行のみ)をoidとdateでフィルタリングするSQLビューを使用することです。

関連する問題