I have to design a report which will be a list of a bunch of overlapping data from the same table.
I have to start with the Project
table because for the report @ProjectId
is the only thing you get as an anchor.
In the RessourceBookings
table are all bookings and some are overlapping like
- Project A books resource B 24.01., 10 a.m. to 6 p.m.
- Project C books resource B 24.01., 11 a.m. to 1 p.m
- Project D books resource B 24.01., 1 p.m. to 4 p.m
These are the one I have to filter for and list all those booking conflicts for Project A.
This is the code I came up with at the moment. I didn't shorten it because I want to show that there are a few dependencies from some tables, which makes it a bit complicated (at least for me). If there are other parts besides the main problem which could be optimised, I would be happy to learn.
DECLARE @ProjectId INT = 8501
SELECT
p.Id AS 'Project-ID'
,p.Name AS 'Project-Name'
,p.Info AS 'Project-Info'
,pc.Name AS 'Project-Color'
,upr.DocumentName AS 'Project-Responsible'
,r.ResourceName AS 'Ressource-Name'
,r.Info AS 'Ressource-Info'
,CASE WHEN ugrr.ResourceRoleId IN (4,7)
THEN 0
ELSE 1
END AS 'Ressource-Availability'
,r.Quantity AS 'Booking-Quantity'
,rb.Start AS 'Booking-Start'
,rb.[End] AS 'Booking-End'
,pat.Name AS 'Booking-Action'
,rb.IsOption AS 'Booking-State'
,rb.OptionRequestAccepted AS 'Booking-Response'
,q2.ProjectId AS 'Conflict-Project-ID'
,q2.Name AS 'Conflict-Project-Name'
,q2.DocumentName AS 'Conflict-Project-Responsible'
,q2.Start AS 'Conflict-Start'
,q2.[End] AS 'Conflict-End'
,q2.IsOption AS 'Conflict-State'
FROM
Projects p
LEFT JOIN
ProjectColors pc ON pc.Id = p.ProjectColorId
LEFT JOIN
Users upr ON upr.Id = p.ResponsibleUserId
LEFT JOIN
ResourceBookings rb ON rb.ProjectId = p.Id
LEFT JOIN
Resources r ON r.Id = rb.ResourceId
LEFT JOIN
ProjectActions pa ON pa.Id = rb.ProjectActionId
LEFT JOIN
ProjectActionTypes pat ON pat.Id = pa.ProjectActionTypeId
LEFT JOIN
UserGroupResourceRoles ugrr ON ugrr.ResourceId = r.Id
LEFT JOIN
(SELECT
p2.ProjectId
,p2.Name
,upr2.DocumentName
,rb2.Start
,rb2.[End]
,rb2.IsOption
FROM
ResourceBookings rb2
LEFT JOIN
Projects p2 ON p2.Id = rb2.ProjectId
LEFT JOIN
Users upr2 ON upr2.Id = p2.ResponsibleUserId
WHERE
rb2.ResourceId = r.Id
AND (rb2.Start BETWEEN DATEADD(s, +1, rb.Start) AND DATEADD(s, -1, rb.[End])
OR rb2.[End] BETWEEN DATEADD(s, +1, rb.Start) AND DATEADD(s, -1, rb.[End])
OR DATEADD(s,+1,rb.Start) BETWEEN rb2.Start AND rb2.[End])) q2
WHERE
p.Id = @ProjectId
AND rb.Start >= SysDateTime()
AND ugrr.UserGroupId = 11
AND (SELECT Count(rb2.Id) - 1
FROM ResourceBookings rb2
WHERE rb2.ResourceId = r.Id
AND (rb2.Start BETWEEN DATEADD(s, +1, rb.Start) AND DATEADD(s, -1, rb.[End])
OR rb2.[End] BETWEEN DATEADD(s, +1, rb.Start) AND DATEADD(s, -1, rb.[End])
OR DATEADD(s, +1, rb.Start) BETWEEN rb2.Start AND rb2.[End])) > 0
My goal is something like:
Project-ID | Project-Name | [...] | Conflict-Project-ID | Conflict-Project-Name | [...] |
---|---|---|---|---|---|
1 | Project A | [...] | 2 | Project B | [...] |
1 | Project A | [...] | 3 | Project C | [...] |
1 | Project A | [...] | 4 | Project D | [...] |
Without the whole q2 parts, it works well to list all the information for Project A.
The errors are:
Wrong syntax near the WHERE-keyword.. Native error: 156. SQLSTATE: 42000. Severity 15. Msg State 1. Line 76.
Wrong syntax near ">".. Native error: 102. SQLSTATE: 42000. Severity 15. MsgState 1. Line 87.
Without the subquery join, it works well but I think I need that there. I've googled the last two days but can't find any solution. In my eyes it seems correct.
I can't change the tables or their content. I have to deal with the setup. So temporary tables are not an option (which maybe could help).
(But please no single-word technical-term-answers. I'm not a developer, I have just to work with these kind of things. I'm willing to learn but it's a bit hard without a professional background)
Edit: For clarifications, here is a picture of the table
ResourceBookings
(top) and bottom the "goal" of the query if @ProjectId = 8525