Reputation: 628
I'm working on a fairly complicated aspect to an Equipment / Asset database in SQL Server and would like to ask for some help please. I'll try and focus on one issue here and then ask a separate question for another problem.
I have a table for equipment called tblEquipment
and a table for required actions that need to be performed on collections of equipment (tblActionsRequired
), for the sake of this question the relevant fields are:
tblEquipment
: EquipmentID, BasedAtID, AreaID
tblRequiredActions
: AllSites (bit), BasedAtID, AreaID
So the idea with tblRequiredActions
is that you'd say all equipment at company Site A needs to be inspected every so often. Areas are specific rooms or offices etc. at a site. So if AllSites is true the action applies to all equipment company-wide, if it's false then BasedAtID (for the site) is required, AreaID is optional if you want to narrow it down even more.
So now the problem to extract which actions should be applied to which equipment based on these three fields.
What I have now is what I think might work but I'm struggling to verify my results as there are other factors confusing me as well, so would really appreciate some confirmation or guidance if I'm completely on the wrong track! I don't want to go the route of stored procedures and if blocks or unions as there are multiple other dimensions that need to be covered with the similar principle and I'll end up writing a massively complicated procedure that will be a nightmare to maintain. Thanks!!
SELECT
dbo.tblActionsRequired.ActionID, dbo.tblEquipment.EquipmentID
FROM
dbo.tblEquipment
INNER JOIN
dbo.tblActionsRequired ON dbo.tblActionsRequired.AllSites = 'True'
OR dbo.tblEquipment.AreaID IS NULL
AND dbo.tblEquipment.BasedAtID = dbo.tblActionsRequired.BasedAtID
OR dbo.tblEquipment.AreaID IS NOT NULL
AND dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaID
Upvotes: 15
Views: 33518
Reputation: 45106
I don't think you need the not null
If AreaID is null then dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaID will evaluate to null
SELECT
dbo.tblActionsRequired.ActionID, dbo.tblEquipment.EquipmentID
FROM
dbo.tblEquipment
INNER JOIN
dbo.tblActionsRequired
ON dbo.tblActionsRequired.AllSites = 'True'
OR dbo.tblEquipment.AreaID IS NULL
AND dbo.tblEquipment.BasedAtID = dbo.tblActionsRequired.BasedAtID
OR dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaID
Upvotes: 1
Reputation: 4848
Looks correct to me; Your logic and approach look sound.
Although the combinations of AND/OR might be open to misinterpretation... Perhaps consider grouping your AND expressions in parenthesis (I know this is redundant, but doing so clarifies your intent). And as per @MarkBannister's recent answer, this might reveal an opportunity for Boolean algebra factorization :-)
I'd personally move any "filtering" out of the inner join's ON clause, into a WHERE clause, leaving just the expressions that relate to the join itself, in the case where there's only one join and those filters are isolated from the join logic itself. But this is not the case here.
Indexes will probably affect this one way or the other... Check your execution plan to see if you'd benefit from adding some on your FKs or the text field.
Upvotes: 2
Reputation:
The existing query looks pretty good to me, although it can be simplified slightly:
SELECT dbo.tblActionsRequired.ActionID, dbo.tblEquipment.EquipmentID
FROM dbo.tblEquipment
JOIN dbo.tblActionsRequired
ON dbo.tblActionsRequired.AllSites = 'True' OR
(dbo.tblEquipment.AreaID IS NULL AND
dbo.tblEquipment.BasedAtID = dbo.tblActionsRequired.BasedAtID) OR
dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaID
- since if both a.AreaID and e.AreaID are null, then the condition dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaID
does not evaluate as true.
(The parentheses aren't strictly required, but were included for clarity.)
Upvotes: 8