0

たとえば、2 つのテーブルがあり、1 つはオブジェクト レコード用で、もう 1 つはこれらのオブジェクトに関するアクティビティ レコード用です。

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

簡単に説明すると、アクティビティ テーブルに 4 つのフィールドがあるとします。objectId、タイプ、ステータス、および日付。

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

SELECT * FROM アクティビティ;

oid タイプの状況報告日
----------------------------------------------
1 0 1 2009.03.05 17:58:07
1 ヌル 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 oid = 1;

oid タイプの状況報告日
----------------------------------------------
1 3 2 2009.03.08 07:00:00

どうすればこれを達成できますか?

4

4 に答える 4

0

MAX関数の使用を検討しましたか?

select oid, type, status, MAX(date) as max_date 
from ObjectStateView 
where oid = 1
于 2009-03-06T13:50:36.573 に答える
0

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

于 2009-03-06T13:51:38.583 に答える
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 と日付でフィルタリングする SQL ビューを使用して、現在の (最新の) バージョンを選択するのは簡単です。

于 2009-05-28T16:43:04.943 に答える
0

日付を使用して最新のレコードを見つけることができると仮定します。

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

編集:JOINが必要な場合(未テスト)

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回触れる必要があるため、指数関数的にスケーリングします。

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

于 2009-03-06T14:01:45.237 に答える