我开发了一个时间表记录系统,允许用户记录:
当他们提交时间表时,系统还会记录他们的GeographyId,RoleId,CategoryId(单个ID)和AttributeIds(多个ID) - 这是用户在该时间点的快照。
然后可以查询记录的时间表信息以获取报告。在最简单的形式中,系统将返回一个UserIds列表,其中每个记录的PeriodMinutes
的SUM为DutyActivityId
。看起来如下:
然而,我还想做的是分组并返回每个时间表记录的记录AttributeIds
(在TimesheetAttribute
表中)。但是,因为每个时间表记录了多个AttributeIds
,所以它更复杂一些。
我的尝试创建了以下报告:
但问题是,每个SUM(PeriodMinutes)
返回的DutyCategoryId
现在太高了。我的SQL似乎为每个时间表包含AttributeIds
导致SUM
计算错误。
我已经创建了一个包含数据库架构和数据的SQL的ZIP,以及我在此处截图的两个查询的SQL:ZIP Timesheet example database
以下信息包含在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
答案 0 :(得分:1)
我设法通过删除第二个PIVOT和AttributeId
GROUP BY参数并在属性上使用LEFT JOIN来获得所需的结果。
SELECT
*
FROM
(
SELECT
T.UserId,
T.RoleId,T.GeographyId,T.CategoryId,
TA.[-1],TA.[-2],TA.[-3],TA.[-4],TA.[-5],
TDA.DutyActivityId AS TypeId,
SUM(TDA.PeriodMinutes) AS Total
FROM
Timesheet AS T
LEFT JOIN
(SELECT TimesheetId,
SUM(CASE WHEN AttributeId ='1' THEN -1 ELSE 0 END) AS [-1],
SUM(CASE WHEN AttributeId ='2' THEN -1 ELSE 0 END) AS [-2],
...
SUM(CASE WHEN AttributeId ='5' THEN -1 ELSE 0 END) AS [-5]
FROM TimesheetAttribute
GROUP BY TimesheetId
)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
ORDER BY UserId ASC