Я бы лично сохранял цели и фактические данные в отдельных строках, и, скорее всего, в отдельных таблицах:
Цели: EmployeeId, PeriodId, ProductId, TargetValue
Продажи: EmployeeId, PeriodId, ProductId, SalesValue
Фактически, в интегрированной системе вторая таблица обычно не нужна (при условии, что у вас есть полная система регистрации продаж, это должна быть проекция / просмотр фактических зарегистрированных продаж - с соответствующим назначениемсотрудник, период и продукт, основанные на модели этой подсистемы).
Для того, чтобы соответствовать вашим календарным требованиям, у меня почти наверняка будет таблица дат, которая позволит вам обеспечить все ваши различные бизнес-правила для определенийнедели и месяцы без сложной логики дат.Затем определение периодов и агрегирование просто облегчается с помощью присоединений к календарной таблице.
Таким образом, ActualSales будет выглядеть примерно так (только с обычной таблицей Period, которая сама может быть таблицей периодов и дат):
SELECT sp.EmployeeId
, p.ProductId
, pd.PeriodType
, pd.PeriodId
, SUM(id.Quantity * id.UnitProce) AS TotalSales
FROM Invoice AS i
INNER JOIN InvoiceDetail AS id
ON id.InvoiceId = i.InvoiceId
INNER JOIN Employee AS sp
ON sp.EmployeeId = i.SalesPersonId
INNER JOIN Product AS p
ON id.ProductId = p.ProductId
INNER JOIN Period AS pd
ON pd.StartDate <= i.InvoiceDate
AND pd.EndDate > i.InvoiceDate
GROUP BY sp.EmployeeId, p.ProductId, pd.PeriodType, pd.PeriodId
В этом случае данные дублировались бы, если бы у вас были перекрывающиеся периоды (например, ежедневные, еженедельные, ежемесячные), поэтому вам нужно будет агрегировать ТОЛЬКО один тип периодов - вот почему я специально включил их вэто примерное представление, хотя здесь это избыточно.
Я ожидаю, что общая таблица периодов будет выглядеть следующим образом:
PeriodId
PeriodType
StartDate
EndDate
Это будет заполнено различными периодами, о которых вы хотите сообщить:
'Q', 1/1/2010, 4/1/2010
'M', 1/1/2010, 2/1/2010
'M', 2/1/2010, 3/1/2010
'M', 3/1/2010, 4/1/2010
'W', 1/3/2010, 1/10/2010
'W', 1/10/2010, 1/17/2010
etc.
'D', 1/1/2010, 1/2/2010
'D', 1/2/2010, 1/3/2010
etc.
Бесполезно беспокоиться о праздниках, за исключением того, что вы, вероятно, не собираетесь назначать цели, если они не работают, и это в основном касается управления назначениями, чтобы они были, по-видимому, реалистичными.У вас может быть календарная таблица дней с различными флагами
Calendar
DateId
Date
IsHoliday
Затем вы можете включить это при присоединении для подсчета количества выходных / праздничных дней в периоде и т. Д.
Обычно этобухгалтерский учет / бизнес, но вы можете посмотреть на стандартизацию вашего календаря.Например, в медиа-покупках для телевизионной рекламы они делают каждый «квартал» равным и стандартизируют каждый «месяц» - 4 недели, 4 недели, 5 недель.Очевидно, что они делают исключения для праздничных и специальных телевизионных мероприятий, но это помогает сгладить учет и легче сравнивать периоды.