Я разработал систему записи расписания, которая позволяет пользователям записывать:
- A Период времени (с 9:00 до 12:00)
- Что они сделали за это время (DutyActivity: 1 час написания отчета, 2 часа обучения)
Когда они отправляют расписание, система также записывает их GeographyId, RoleId,CategoryId (одиночные идентификаторы) и AttributeIds (множественные идентификаторы) - это снимок пользователя на тот момент времени.
Эта записанная информация расписания может быть запрошена для отчетов.В простейшей форме система вернет список идентификаторов пользователей с суммой PeriodMinutes
для каждого записанного DutyActivityId
.Что будет выглядеть следующим образом:

Однако я также хочу сгруппировать и вернуть записанные AttributeIds
, записанные с каждым расписанием (в таблице TimesheetAttribute
).).Однако, поскольку для каждого расписания записано несколько AttributeIds
, это немного сложнее.
Моя попытка создать следующий отчет:

Однако проблема в том, что в том, что SUM(PeriodMinutes)
для каждого возвращенного DutyCategoryId
теперь слишком велико.Похоже, что мой SQL включает AttributeIds
для каждого расписания, что приводит к неправильным вычислениям SUM
.
Я создал ZIP, содержащий SQL для схемы базы данных плюс данные вместе с SQL дляна оба запроса я сделал скриншот: Пример базы данных ZIP
Информация ниже включена в ZIP, но я привожу их здесь для простоты доступа:

Отчет по расписанию без группировки атрибутов
SELECT
*
FROM
(
SELECT
T.UserId,
T.RoleId,T.GeographyId,T.CategoryId,
TDA.DutyActivityId AS TypeId,
SUM(TDA.PeriodMinutes) AS Total
FROM
Timesheet AS T
LEFT JOIN
TimesheetDutyActivity AS TDA ON
TDA.TimesheetId = T.TimesheetId
GROUP BY
T.UserId,
T.RoleId,T.GeographyId,T.CategoryId,
TDA.DutyActivityId
) AS SourceTable
/* PIVOT against the known DutyActivityIds */
PIVOT
(
SUM(Total)
FOR TypeId IN ([1],[2],[3],[4],[5])
)
AS PivotType
ORDER BY UserId ASC
Отчет по расписанию с попытками атрибутовгруппировка
SELECT
*
FROM
(
SELECT
T.UserId,
T.RoleId,T.GeographyId,T.CategoryId,
TA.AttributeId * -1 AS AttributeId, /* Multiply AttributeId by -1 in order to create negative Ids, so that two PIVOT operations can be used */
TDA.DutyActivityId AS TypeId,
SUM(TDA.PeriodMinutes) AS Total
FROM
Timesheet AS T
LEFT JOIN
TimesheetAttribute AS TA ON
TA.TimesheetId = T.TimesheetId
LEFT JOIN
TimesheetDutyActivity AS TDA ON
TDA.TimesheetId = T.TimesheetId
GROUP BY
T.UserId,
AttributeId,
T.RoleId,T.GeographyId,T.CategoryId,
TDA.DutyActivityId
) AS SourceTable
/* PIVOT against the known DutyActivityIds */
PIVOT
(
SUM(Total)
FOR TypeId IN ([1],[2],[3],[4],[5])
)
AS PivotType
/* Also PIVOT against the known AttributeIds */
PIVOT
(
SUM(AttributeId)
FOR AttributeId IN ([-1],[-2],[-3],[-4],[-5])
)
AS PivotAttribute
ORDER BY UserId ASC