Conditional SQL Join using a 3rd table

2019-09-19 17:02发布

问题:

I've got a problem with an Asset Database that I have been developing for a customer in MSSQL. It entails capturing Required Actions, for example Lifting Equipment at a specific location needs to be inspected 6 months after purchase. The Due Dates for these required actions can be calculated in different ways but to simplify here will be calculated based on their Purchase Date.

So to that end I have a table called tblActionsRequired that contains the following relevant fields:

  • ActionID - for the action required
  • EquipmentCategoryID or EquipmentTypeID or EquipmentID - so either one of these fields are required. With this they specify that an action is required for either a category of equipment or an equipment type or a specific piece of equipment. So an example would be that a 2kg Powder Fire Hydrant would be an equipment type, it would fall into the category Fire Safety Equipment and there might be a specific 2kg Powder Fire Hydrant with an asset number of say PFH2KG001.
  • BasedAtID - the company's branches or sites

Ideally what I'd like to do is keep as much as possible in one query as opposed to creating separate queries or views for every combination and then adding them together using UNIONs. I have several other similar fields by which these required actions can be segmented so it may seem simple enough here to just use unions but I've calculated I would need to cater for 48 different combinations and probably create a View for each and then UNION them together!

So next I have tblEquipment that contains the following relevant keys:

  • EquipmentID - the primary key
  • EquipmentTypeID = foreign key, which Equipment Type this asset is a member of
  • BasedAtID - foreign key, which site the asset is located at

The Equipment Types then belong to Equipment Categories and the Categories then allow building a tree structure with parent-child relationships, but these I think I have sufficiently taken care of in creating a view called vwCategoryTree with the following fields:

  • ParentCategoryID
  • EquipmentTypeID

This view has been tested and checks out fine, it cuts through the tree structure and allows you to perform joins between EquipmentTypeID and their ultimate parents with EquipmentCategoryID.

What I need help with is how to do some sort of conditional join between tblActionsRequired and tblEquipment based on which of the fields EquipmentCategoryID, EquipmentTypeID, or EquipmentID have a value. If only EquipmentID or EquipmentTypeID could be specified then I think this would work:

ON (tblActionsRequired.EquipmentID IS NOT NULL AND tblEquipment.EquipmentID = tblActionsRequired.EquipmentID) OR (tblActionsRequired.EquipmentTypeID IS NOT NULL AND tblActionsRequired.EquipmentTypeID = tblEquipment.EquipmentTypeID)

But how do I bring a third table into this join to cater for EquipmentCategoryID or at least avoid having to use a UNION?

Sorry if something doesn't make sense, please just ask! Thank you very much!

回答1:

One possible approach:

select ...
from tblEquipment e
left join vwCategoryTree c on e.EquipmentTypeID = c.EquipmentTypeID
join tblActionsRequired r 
  on (e.EquipmentID = r.EquipmentID or 
      e.EquipmentTypeID = r.EquipmentTypeID or 
      c.ParentCategoryID = r.EquipmentCategoryID)