问题描述
我需要编写一个 sql 代码来从我的一个表中导出一份报告,如下所示:
EmployeeId Date ProjectId Hours Approved
123 12/7 A1 8 Y
123 12/8 A1 5 Y
123 12/9 A2 6 Y
123 12/9 A1 2 Y
123 12/14 A1 8 Y
123 12/15 A1 5 N
123 12/16 A2 6 Y
123 12/16 A1 2 Y
123 12/21 A1 8 Y
123 12/22 A1 5 Y
123 12/23 A2 6 Y
123 12/23 A1 2 Y
我期望的报告格式是:
EmployeeId Project WeekStart SundayHours MondayHours TuesdayHours WednesdayHours ThursdayHours FridayHours SaturdayHours
123 A1 12/7 0 8 5 2
123 A2 12/7 0 0 0 6
123 A1 12/21 0 8 5 2
123 A2 12/21 0 0 0 6
还有一个条件。只有当他的整周时间得到批准时,我才需要包含员工记录。在上面的示例中,12/15 的小时数未获批准。因此,报表中不显示 12/14 周的记录。
此外,我只需要包含最近 3 周的数据。也就是说,如果报表是在 12/26 运行的,它应该给出 12/7、12/14 和 12/21 周的记录。
我不知道从哪里开始。谁能帮我生成这样的报告
解决方法
我建议操纵日期作为分组机制,然后简单地进行一些条件求和。
日期的美妙之处在于,您可以轻松提取周几名称、周数等内容。在本示例中,我使用周数来过滤掉具有未批准记录的周(请参阅 JOIN),以及获取最短日期(WeekStart)。
然而,这并非万无一失。如果没有星期一记录,那么 WeekStart 可能不是您所期望的
SELECT
EmployeeId,ProjectId,WeekStart,SUM(IIF(DATENAME(WEEKDAY,Date)='Sunday',Hours,0)) SundayHours,Date)='Monday',0)) MondayHours,Date)='Tuesday',0)) TuesdayHours,Date)='Wednesday',0)) WednesdayHours,Date)='Thursday',0)) ThursdayHours,Date)='Friday',0)) FridayHours,Date)='Saturday',0)) SaturdayHours
FROM #WorkHours WH
INNER JOIN
(
SELECT
DATEPART(WEEK,Date) WeekNumber,MIN(Date) WeekStart
FROM #WorkHours
GROUP BY
DATEPART(WEEK,Date)
HAVING SUM(IIF(Approved='N',1,0)) = 0
) Approved
ON DATEPART(WEEK,WH.Date) = Approved.WeekNumber
GROUP BY
EmployeeId,ProjectId
ORDER BY
EmployeeId,ProjectId
,
SQL Server 将周定义为从星期日开始。您的数据中没有年份,所以让我假设这就是您的意图。
然后你可以简单地使用条件聚合:
select EmployeeId,dateadd(day,7 - datepart(weekday,Date)) as week,sum(case when datename(weekday,Date) = 'Sunday' then Hours else 0 end) as sunday_hours,Date) = 'Monday' then Hours else 0 end) as monday_hours,. . .
from #WorkHours wh
group by EmployeeId,Date)),ProjectId