【问题标题】:Conditional SQL Join using a 3rd table使用第三个表的条件 SQL 连接
【发布时间】:2013-04-02 12:26:49
【问题描述】:

我一直在为 MSSQL 中的客户开发的资产数据库存在问题。它需要捕获Required Actions,例如在特定位置的Lifting Equipment 需要在购买后6 个月进行检查。这些所需操作的Due Dates 可以用不同的方式计算,但为了简化,这里将根据它们的Purchase Date 计算。

为此,我有一个名为 tblActionsRequired 的表,其中包含以下相关字段:

  • ActionID - 所需操作
  • EquipmentCategoryIDEquipmentTypeIDEquipmentID - 所以这些字段中的任何一个都是必需的。有了这个,他们指定一个设备类别或设备类型或特定设备需要一个操作。例如,2kg 粉末消火栓是一种设备类型,它属于消防安全设备类别,并且可能有一个特定的 2kg 粉末消火栓,其资产编号为 PFH2KG001。
  • BasedAtID - 公司的分支机构或站点

理想情况下,我想做的是尽可能多地保留在一个查询中,而不是为每个组合创建单独的查询或视图,然后使用 UNION 将它们添加在一起。我还有其他几个类似的字段,可以通过这些字段对这些必需的操作进行分段,因此在这里使用联合似乎很简单,但我计算出我需要满足 48 种不同的组合,并可能为每个组合创建一个视图,然后将它们联合起来一起!

接下来我有tblEquipment,其中包含以下相关键:

  • EquipmentID - 主键
  • EquipmentTypeID = 外键,该资产属于哪个设备类型
  • BasedAtID - 外键,资产所在的站点

Equipment Types 然后属于Equipment Categories,然后类别允许构建具有父子关系的树结构,但是我认为我在创建一个名为vwCategoryTree 的视图时已经充分注意了以下字段:

  • ParentCategoryID
  • EquipmentTypeID

这个视图已经过测试并且检查良好,它可以切开树形结构,并允许您在EquipmentTypeID 和它们的最终父级与EquipmentCategoryID 之间执行连接。

我需要帮助的是如何根据 EquipmentCategoryID、EquipmentTypeID 或 EquipmentID 中的哪些字段具有值来在 tblActionsRequired 和 tblEquipment 之间进行某种条件连接。如果只能指定 EquipmentID 或 EquipmentTypeID,那么我认为这会起作用:

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

但是我如何将第三个表引入此联接以适应 EquipmentCategoryID 或至少避免使用 UNION?

如果有什么不明白的地方,请尽管问!非常感谢!

【问题讨论】:

  • 为什么要避免使用联合查询?
  • 谢谢@DanBracuk,只是我有几个类似的字段需要根据它们的值进行不同的连接。对于每个额外的字段,我必须联合在一起的查询数量呈指数增长。如果客户想让我改变任何东西,那绝对是一场噩梦
  • 从您所说的看来,在类别中似乎可以有许多级别的设备类别。如果是这样,所需操作的设备类别可以位于类别层次结构的任何级别,还是仅位于顶层? vwCategoryTree 是否具有所有类别级别的 ParentCategoryID 值,除最低级别之外的所有级别或仅顶级级别?
  • 感谢@MarkBannister,它可以在任何级别,并且视图包含所有级别

标签: sql sql-server tsql


【解决方案1】:

一种可能的方法:

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)

【讨论】:

  • 太棒了,如此简单,绝对有道理,谢谢!我要去试一试,但看不出这是怎么回事,真的很感激@markbannister!
  • @eboyens:很高兴我能帮上忙——我希望它能帮到你!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-02-15
  • 1970-01-01
  • 2013-11-18
  • 1970-01-01
  • 1970-01-01
  • 2020-08-05
  • 1970-01-01
相关资源
最近更新 更多