Reputation: 21
I have a table with 3 fields "Start Date" and "End Date" and "Allocation %". I will need to find out all the records in this table which falls within 3 months from the current date,
And (this one is tricky) only the records with overlapped date ranges where the Sum(Allocation %) > 100.
Please help me to come up with a query.
This is the table schema.
Table (ResourceAssignment)
- ResourceAssignmentID (PK)
- ResourceID (FK)
- Assigned To (FK)
- Start Date
- End Date
- Allocation %
I will basically need to find all over allocated resources within a certain period (from current day to 3 months).
Thanks in advance!
Upvotes: 0
Views: 1556
Reputation: 1
I assume that Start Date and End date are formatted as Date time or Date.
I'm not sure if you are trying to determine if the start date records fall within the past 3 months or the end date records.
Also you'll need a limit to determine the Sum(Allocation %). What unique records are you wanting to sum. Since you want to Sum Allocation % and then select only the ones that are greater than 100, you have to figure out which ones to pull then to sum.
You'll want to accomplish this using a With statement or creating sub "tables" (queries) that pull the information you want in stages. I'll present the subquery statements.
Written for Sql-Server 2008 R2
First Select data that is within the Past 3 months
Select ResourceAssignmentID, ResourceID, [Assigned To], [Allocation %]
From ResourceAssignment
Where [Start Date] >= dateadd(Month,-3,Now)
Then using this data you want to Sum the Allocation %. (I am assuming based on the combination of the 2 foreign keys)
Select Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %]) as Sumofallocation
From
(Select ResourceAssignmentID, ResourceID, [Assigned To], [Allocation %]
From ResourceAssignment
Where [Start Date] >= dateadd(Month,-3,Now)) Query1
Group By Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %])
You may be able to add the Where statement before the group by to filter out for your >100 requirement, but I would just add another Select statement to pull it all together
Select * From
(Select Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %]) as Sumofallocation
From
(Select ResourceAssignmentID, ResourceID, [Assigned To], [Allocation %]
From ResourceAssignment
Where [Start Date] >= dateadd(Month,-3,Now)) Query1
Group By Query1.ResourceID, Query1.[Assigned To], sum(Query1.[Allocation %])
) Query2
Where Query2.Sumofallocation > 100
Also, it seems like you are working on a project management type program. Would Microsoft Project not work? You would be able to see who's over allocated in whatever time-frame you wished. If you have multiple projects, you could just merge them into one large Project file and see it that way...
Anyway, I hopes this helps. The SQL might not be perfect, but it should point you in a workable direction.
Upvotes: 0
Reputation: 7239
I think this is what you try to achieve :
SELECT SUM(Allocation), ResourceID
FROM ResourceAssignment
WHERE EndDate BETWEEN GETDATE() AND DATEADD(m,3,GETDATE())
GROUP BY ResourceID
HAVING SUM(Allocation) > 100
Upvotes: 0
Reputation: 10918
You have two general solutions. Which is best is dependent on the size of ResourceAllocation, the frequency of conflicts, and how you intend to present the data.
Solution 1: Make a list of dates in the next 3 months and join against that to identify which dates are overallocated
WITH
datelist AS (
SELECT CAST(GETDATE() AS date) [d] UNION ALL SELECT DATEADD(day,1,[d]) FROM datelist WHERE [d] < DATEADD(month,3,GETDATE())
),
allocations AS (
SELECT *,SUM([Allocation %]) OVER(PARTITION BY [ResourceID],[d]) AS [Total Allocation %]
FROM datelist
INNER JOIN ResourceAssignment ON ([d] BETWEEN [Start Date] AND [End Date])
)
SELECT *
FROM allocations
WHERE [Total Allocation %] >= 100
Solution 2: Use a range-conflict query with a self-join on ResourceAssignment
SELECT *
FROM (
SELECT
t1.*,SUM(t1.[Allocation %]) OVER(PARTITION BY t1.[ResourceID]) AS [Total Allocation %]
FROM ResourceAssignment t1
INNER JOIN ResourceAssignment t2 ON (
t1.[ResourceID] = t2.[ResourceID] AND
t1.[ResourceAssignmentID] <> t2.[ResourceAssignmentID] AND
t1.[Start Date] < t2.[End Date] AND
t2.[Start Date] < t1.[End Date]
)
WHERE
t1.[Start Date] <= CAST(GETDATE()+30 as date) AND
t2.[Start Date] <= CAST(GETDATE()+30 as date) AND
t1.[End Date] > CAST(GETDATE() as date) AND
t2.[End Date] > CAST(GETDATE() as date)
) t
WHERE [Total Allocation %] >= 100
Upvotes: 1
Reputation: 34784
Not exactly sure if this is what you're after, but this would show you all ResourceID with allocation above 100% where their begin or end date is within the last 3 months:
SELECT ResourceID
FROM ResourceAssignment
WHERE StartDate BETWEEN DATEADD(month,-3,GETDATE()) AND GETDATE()
OR EndDate BETWEEN DATEADD(month,-3,GETDATE()) AND GETDATE()
GROUP BY ResourceID
HAVING SUM([Allocation %]) > 100
Upvotes: 1