[英]SQL SUM hours by week across number of years
I have a table in a SQL database that holds information about the hours worked by employees across a number of years. 我在SQL数据库中有一个表,其中包含有关员工多年工作时间的信息。 Each employee can have more than one record for a specific date and each employees start date can be different.
每个雇员在特定日期可以有多个记录,并且每个雇员的开始日期可以不同。
I am trying to sum the weekly hours of each employee based on their first week. 我试图根据每个员工的第一周来总结他们的每周工作时间。 So if the employee started on the 17/04/2018 any hours logged in this week would be considered week 1 for this employee and the following week would be week two etc. For another employee week one could start in a different day/month/year etc.
因此,如果该员工于2018年4月17日开始工作,则本周登录的任何时间都将被视为该员工的第1周,而下一周则是第二周,以此类推。对于另一位员工,一周可以在不同的日期/月份/年等
My data includes the following fields: 我的数据包括以下字段:
Sequence_ID: relates to an individual employee Sequence_ID:与单个员工有关
Date_European: relates to each date an employee has logged hours with the minimum of this being the first date the employee started in the company Date_European:与员工记录的每个小时相关的日期,其中最少的时间是该员工在公司开始的首次日期
Hours: The amount of hours logged 小时:记录的小时数
I also have a year field in the data which is the year of the Date_European column. 我在数据中还有一个Year字段,它是Date_European列的年份。
The below is what I have attempted but I know it isn't even close to the format I need. 以下是我尝试过的内容,但我知道它甚至与我需要的格式不符。
select
Sequence_ID
,DATEPART(week,Date_European) AS Week
,DATEPART(year,Date_European) AS Year
,SUM([Hours]) AS Weekly_Hours
from [AB_DCU_IP_2018].[dbo].[mytable]
group by
Sequence_ID
,DATEPART(week,Date_European)
,DATEPART(year,Date_European)
order by
Sequence_ID
,DATEPART(week,Date_European)
,DATEPART(year,Date_European)
I tried to create the 'Week' field. 我尝试创建“周”字段。 From the above code it just gives me what week of a particular year a date relates to.
从上面的代码中,它仅能告诉我日期与特定年份的哪个星期相关。 I then added the 'Year' column to distinguish between different years, but again this only gives me what particular year that is.
然后,我添加了“年份”列以区分不同的年份,但这再次仅给出了特定的年份。
Is there any way to create a 'Week' field in the format I am looking for? 有什么方法可以按照我想要的格式创建“周”字段? (Week of earliest date and surrounding dates would be week 1).
(最早的日期和周围的日期是第1周)。
I was attempting to use the rank and partition by function by couldn't get this to work properly. 我试图按功能使用等级和分区,无法使其正常工作。
Any help would be greatly appreciated as I have been searching for a solution for hours. 任何帮助将不胜感激,因为我一直在寻找解决方案数小时。
Thanks in advance. 提前致谢。
EDIT: How to create the initial table 编辑:如何创建初始表
CREATE TABLE mytable(Sequence_ID VARCHAR(6) NOT NULL ,Date_European DATE NOT NULL ,Hours NUMERIC(5,1) NOT NULL);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/05/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/06/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/07/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/08/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/09/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/12/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/13/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/14/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/15/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/16/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/19/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/20/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/21/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/22/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/23/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/26/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/27/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/28/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/29/2016',7.3);
INSERT INTO mytable(Sequence_ID,Date_European,Hours) VALUES ('da6Wrw','09/30/2016',7.3);
What I want as the desired outcome: 我想要的结果是什么:
| Sequence_ID | Date_European | DATEPART(week,Date_European) | Hours | Desired_OutCome_Week |
| da6Wrw | 05/09/2016 | 37 | 7.3 | 1 |
| da6Wrw | 06/09/2016 | 37 | 7.3 | 1 |
| da6Wrw | 07/09/2016 | 37 | 7.3 | 1 |
| da6Wrw | 08/09/2016 | 37 | 7.3 | 1 |
| da6Wrw | 09/09/2016 | 37 | 7.3 | 1 |
| da6Wrw | 12/09/2016 | 38 | 7.3 | 2 |
| da6Wrw | 13/09/2016 | 38 | 7.3 | 2 |
| da6Wrw | 14/09/2016 | 38 | 7.3 | 2 |
| da6Wrw | 15/09/2016 | 38 | 7.3 | 2 |
| da6Wrw | 16/09/2016 | 38 | 7.3 | 2 |
| da6Wrw | 19/09/2016 | 39 | 7.3 | 3 |
| da6Wrw | 20/09/2016 | 39 | 7.3 | 3 |
| da6Wrw | 21/09/2016 | 39 | 7.3 | 3 |
| da6Wrw | 22/09/2016 | 39 | 7.3 | 3 |
| da6Wrw | 23/09/2016 | 39 | 7.3 | 3 |
| da6Wrw | 26/09/2016 | 40 | 7.3 | 4 |
| da6Wrw | 27/09/2016 | 40 | 7.3 | 4 |
| da6Wrw | 28/09/2016 | 40 | 7.3 | 4 |
| da6Wrw | 29/09/2016 | 40 | 7.3 | 4 |
| da6Wrw | 30/09/2016 | 40 | 7.3 | 4 |
Set DateFirst 1
select
Sequence_ID,
(datediff(day , DQ.WeekStarted, Date_European) / 7 + 1) EmployeeWeekNumber
,SUM([Hours]) AS Weekly_Hours
--into [AB_DCU_IP_2018].[dbo].[Weekly_Work_Hours_Employee]
from [AB_DCU_IP_2018].[dbo].[All_IPower_HR_Assurance_4]
CROSS APPLY (SELECT DATEADD(day, -1 * (datepart(weekday,start_date) % 7), start_date) AS WeekStarted
FROM YourTable
WHERE <condition to get the start_date you need>
) DQ
group by
Sequence_ID,
(datediff(day , DQ.WeekStarted, Date_European) / 7 + 1)
order by
Sequence_ID
,DATEPART(week,Date_European)
,DATEPART(year,Date_European)
Here is another approach using the sample data you posted. 这是使用您发布的样本数据的另一种方法。
select mt.Sequence_ID
, mt.Date_European
, DATEPART(week, mt.Date_European)
, mt.Hours
, MyRow.GroupNum
from mytable mt
join
(
select WeekNum = DATEPART(week,Date_European)
, GroupNum = ROW_NUMBER() over(order by DATEPART(week,Date_European))
from mytable
group by DATEPART(week,Date_European)
) MyRow on MyRow.WeekNum = DATEPART(week, mt.Date_European)
try this 尝试这个
select *,rn-1 [Employee_week] from (
select *,dense_RANK() over(Partition by Sequence_ID order by iif(weekly_hours=0,0,week) ) [rn] from (
select
Sequence_ID
,DATEPART(week,Date_European) AS Week
,DATEPART(year,Date_European) AS Year
,SUM([Hours]) AS Weekly_Hours
--into [AB_DCU_IP_2018].[dbo].[Weekly_Work_Hours_Employee]
from [AB_DCU_IP_2018].[dbo].[All_IPower_HR_Assurance_4]
group by
Sequence_ID
,DATEPART(week,Date_European)
,DATEPART(year,Date_European)
order by
Sequence_ID
,DATEPART(week,Date_European)
,DATEPART(year,Date_European))a)a
where rn = 2
This'll give you the hours each employee worked on their first week, use rn>2 to get the remaining weeks 这将为您提供每个员工在第一周工作的时间,使用rn> 2来获取剩余的几周
I actually found an easier way to calculate the week number of the employee that uses the DENSE_Rank function. 实际上,我发现了一种更简单的方法来计算使用DENSE_Rank函数的员工的工作周数。
I have included this below incase anyone as similar issues. 如果有人出现类似问题,我将在下面列出。 I have commented out the DATEPART sections as I was only using these columns as a check to ensure it was working correctly:
我已将DATEPART部分注释掉,因为我只是使用这些列作为检查以确保其正常工作:
select
Sequence_ID
,Date_European
--,DATEPART(week,Date_European) AS Week
--,DATEPART(year,Date_European) AS Year
,DENSE_RANK() OVER (PARTITION BY Sequence_ID ORDER BY DATEPART(year,Date_European), DATEPART(week,Date_European) asc) AS EmployeeWeekNumber
,Hours
from [AB_DCU_IP_2018].[dbo].[All_IPower_HR_Assurance_4]
order by
Sequence_ID
,Date_European
--,DATEPART(week,Date_European)
--,DATEPART(year,Date_European)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.