как создать представление mssql для получения информации о последнем состоянии

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

  •  03-07-2019
  •  | 
  •  

Вопрос

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

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

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

когда объект вот-вот будет обновлен, я планирую получить последнее состояние объекта и посмотреть на изменения.если есть разница между обновляющимся значением и предыдущим значением, я установлю значение с новыми входными данными, в противном случае я установлю его равным 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

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

Это было полезно?

Решение

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

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 раз подряд.

Лучшим решением было бы поддерживать "текущую" таблицу и поддерживать ее с помощью триггера activity.

Другие советы

Рассматривали ли вы возможность использования МАКС. функция?

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

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

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

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

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

Учет результатов работы:

С другой стороны, если у вас больше нескольких полей, а таблица большая, производительность может стать проблемой.В этом случае мне также имело бы смысл хранить / кэшировать все значения целиком в другой таблице Мои данные История, который содержал бы данные, подобные приведенной выше таблице.Затем выбрать текущую (последнюю) версию тривиально, используя представление SQL, фильтрующее последнюю строку (только 1 строку) по oid и дате.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top