First let's slap together some test data. Providing example DDL and DML is very helpful when you ask questions like this:
DECLARE @TABLE TABLE (Location NVARCHAR(50), Name NVARCHAR(50), Date DATE, Hours INT)
INSERT INTO @TABLE (Location, Name, Date, Hours) VALUES
('USA', 'John S', '2022-12-01', 10),('USA', 'John S', '2022-12-02', 10),('USA', 'John S', '2022-12-03', 10),('USA', 'John S', '2022-12-04', 10),('USA', 'John S', '2022-12-05', 10),
('USA', 'Alex P', '2022-12-01', 5),('USA', 'Alex P', '2022-12-02', 5),('USA', 'Alex P', '2022-12-03', 5),('USA', 'Alex P', '2022-12-04', 5),('USA', 'Alex P', '2022-12-05', 5),
('USA', 'Christine H', '2022-12-01', 5),('USA', 'Christine H', '2022-12-02', 5),('USA', 'Christine H', '2022-12-03', 5),('USA', 'Christine H', '2022-12-04', 5),('USA', 'Christine H', '2022-12-05', 5)
INSERT INTO @TABLE (Location, Name, Date, Hours)
SELECT Location, Name, DATEADD(YEAR, -1, Date), Hours / 2
FROM @TABLE
UNION ALL
SELECT Location, Name, DATEADD(YEAR, -2, Date), Hours / 2
FROM @TABLE
I just threw some off the cuff values in the table, and then manipulated it to get a couple more years for the same dates.
You can use this data to mock up something similar to what you have as the desired output using some aggregation using the DATEPART
function and then PIVOT
like this:
SELECT a.Location, Week, a.Name, a.WeekOne, a.WeekTwo, a.WeekThree
FROM (
SELECT Location, Name, DATEPART(WEEK,Date) AS Week,
SUM(CASE WHEN DATEPART(YEAR,Date) = 2020 THEN Hours END) OVER (PARTITION BY Location, Name, DATEPART(WEEK,Date) ORDER BY (SELECT 1)) AS WeekOne,
SUM(CASE WHEN DATEPART(YEAR,Date) = 2021 THEN Hours END) OVER (PARTITION BY Location, Name, DATEPART(WEEK,Date) ORDER BY (SELECT 1)) AS WeekTwo,
SUM(CASE WHEN DATEPART(YEAR,Date) = 2022 THEN Hours END) OVER (PARTITION BY Location, Name, DATEPART(WEEK,Date) ORDER BY (SELECT 1)) AS WeekThree
FROM @TABLE
) a
GROUP BY a.Location, a.Name, Week, a.WeekOne, a.WeekTwo, a.WeekThree
Location Name weekNumber weekOne weekTwo weekThree
-------------------------------------------------------------
USA Alex P 49 10 8 15
USA Christine H 49 10 8 15
USA John S 49 25 20 30
This does make some assumptions. You say 'specific week of the year' which I inferred to mean the ISO week number (1-53). If that's not the case, you can group by what ever definition you need instead.
If you're not a fan of PIVOT
then you could instead have some fun with windowed functions:
SELECT a.Location, Week, a.Name, a.WeekOne, a.WeekTwo, a.WeekThree
FROM (
SELECT Location, Name, DATEPART(WEEK,Date) AS Week,
SUM(CASE WHEN DATEPART(YEAR,Date) = 2020 THEN Hours END) OVER (PARTITION BY Location, Name, DATEPART(WEEK,Date) ORDER BY (SELECT 1)) AS WeekOne,
SUM(CASE WHEN DATEPART(YEAR,Date) = 2021 THEN Hours END) OVER (PARTITION BY Location, Name, DATEPART(WEEK,Date) ORDER BY (SELECT 1)) AS WeekTwo,
SUM(CASE WHEN DATEPART(YEAR,Date) = 2022 THEN Hours END) OVER (PARTITION BY Location, Name, DATEPART(WEEK,Date) ORDER BY (SELECT 1)) AS WeekThree
FROM @TABLE
) a
GROUP BY a.Location, a.Name, Week, a.WeekOne, a.WeekTwo, a.WeekThree
I think this is a little easier to read, and lends itself to using parameters better than the pivot method, but you're still stuck with manual columns.
Location Week Name WeekOne WeekTwo WeekThree
---------------------------------------------------------
USA 49 Alex P 10 8 15
USA 50 Alex P NULL 2 10
USA 49 Christine H 10 8 15
USA 50 Christine H NULL 2 10
USA 49 John S 25 20 30
USA 50 John S NULL 5 20