Как лучше хранить дополнительные параметры сущности в бд?
В базе данных есть 2 таблицы: Акты и История
Для отображения информации пользователю довольно часто мне приходится писать запросы следующего вида:
SELECT
a.Number
, created.AuthorId
, status.StatusId
, status.Timestamp
, verified.Timestamp AS Verified
, implemented.Timestamp AS Implemented
FROM Acts a
OUTER APPLY(SELECT TOP 1 * FROM ActHistories WHERE ActId = a.Id ORDER BY Id) created
OUTER APPLY(SELECT TOP 1 * FROM ActHistories WHERE ActId = a.Id ORDER BY Id Desc) status
OUTER APPLY(SELECT TOP 1 Timestamp FROM ActHistories WHERE ActId = a.Id AND StatusId = 947 ORDER BY Id Desc) verified
OUTER APPLY(SELECT TOP 1 Timestamp FROM ActHistories WHERE ActId = a.Id AND StatusId = 946 ORDER BY Id Desc) implemented
Подумываю насчет создания дополнительной таблицы в которой буду фиксировать данные для исключения запросов OUTER APPLY, схема бд изменится следующим образом
соответственно запрос изменится следующим образом
SELECT
a.Id
, aa.OwnerId
, aa.StatusId
, aa.Timestamp
, aa.Timestamp AS Verified
, aa.Timestamp AS Implemented
FROM Acts a
JOIN ActAttributes aa ON a.Id = aa.ActId
Подскажите можно ли так сделать или может лучше поля из ActAttributes сделать в таблице Acts?
Ответы (1 шт):
Автор решения: Solt
→ Ссылка
Я бы структуру не менял, таблица с историей статусов вполне нормальная. Но можно попробовать оконные функции:
SELECT
a.Number
, MAX(h.AuthorId) OVER (PARTITION BY h.ActId ORDER BY h.Id) AuthorId
, MAX(h.StatusId) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) StatusId
, MAX(h.Timestamp) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) Timestamp
, MAX(CASE WHEN h.StatusId = 947 THEN h.Timestamp END) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) Verified
, MAX(CASE WHEN h.StatusId = 946 THEN h.Timestamp END) OVER (PARTITION BY h.ActId ORDER BY h.Id DESC) Implemented
FROM Acts a
LEFT JOIN ActHistories h ON h.ActId = a.Id
GROUP BY a.Id
Может ошибся с сортировкой окон, тогда поменять MAX/MIN (или ASC/DESC)

