как создать представление mssql для получения последней информации о состоянии - PullRequest
0 голосов
/ 06 марта 2009

Допустим, у меня есть две таблицы: одна для записей об объектах и ​​одна для записей об этих объектах.

Я вставляю новую запись в эту таблицу активности каждый раз, когда объект вставляется или обновляется.

для того, чтобы сказать это простым способом, предположим, у меня есть четыре поля в таблице активности; objectId, тип, статус и дата.

когда объект будет обновлен, я планирую получить последнее состояние для объекта и посмотреть изменения. если есть разница между значением обновления и предыдущим значением, я установлю значение с новым вводом, иначе я установлю его на нуль. так, например, в процессе обновления пользователь только изменяет значение состояния объекта, но оставляет значение типа таким же, поэтому я вставлю новую строку с нулевым значением для типа и новым значением для статуса. *

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

как мне добиться этого _?

Ответы [ 4 ]

0 голосов
/ 28 мая 2009

Исторические ценности:

Поскольку вы отслеживаете изменения, возможно, вы захотите просмотреть статус объекта исторически:

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 , которая будет содержать данные, как в таблице, показанной выше. Затем выбор текущей (последней) версии тривиален с использованием представления SQL, фильтрующего последнюю строку (только 1 строку) по oid и дате.

0 голосов
/ 06 марта 2009

Не совсем уверен, почему вы хотите, чтобы там были нули. Вы можете отслеживать, что изменилось между входами, сравнивая последнюю запись с предыдущей. Тогда текущим состоянием объекта является самая последняя запись в таблице. Вы можете определить, изменился ли объект, создав хэш частей объекта, для которого вы хотите отслеживать изменения, и сохранив его как дополнительный столбец.

0 голосов
/ 06 марта 2009

Предполагается, что дата может быть использована для поиска последней записи:

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

Редактировать: если вы хотите присоединиться (не проверено)

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 голосов
/ 06 марта 2009

Рассматривали ли вы использование функции MAX ?

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