SQL Server条件连接基于列值

时间:2013-03-27 14:00:37

标签: sql sql-server tsql

我正在为SQL Server中的设备/资产数据库做一个相当复杂的方面,并且想请求一些帮助。我会尝试在这里专注于一个问题,然后针对另一个问题提出单独的问题。

我有一个名为tblEquipment的设备表和一个需要对设备集合(tblActionsRequired)执行的操作的表,为了这个问题,相关字段是:< / p>

  • tblEquipmentEquipmentID, BasedAtID, AreaID
  • tblRequiredActionsAllSites (bit), BasedAtID, AreaID

所以tblRequiredActions的想法就是你要说公司A站的所有设备都需要经常检查。区域是一个站点的特定房间或办公室等。因此,如果AllSites为真,则该操作适用于公司范围内的所有设备,如果它是假的,那么需要BasedAtID(对于该站点),如果您想要将其缩小范围,则AreaID是可选的。

现在问题是根据这三个字段提取应该对哪些设备应用哪些动作。

我现在所拥有的是我认为可行的,但我正在努力验证我的结果,因为还有其他因素让我感到困惑,所以如果我完全走错了路,我会非常感谢一些确认或指导!我不想走存储过程的路线,如果是块或联合,因为有许多其他维度需要用相似的原则来涵盖,我最终会编写一个大规模复杂的程序,这将是一个噩梦来维持。谢谢!

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

3 个答案:

答案 0 :(得分:6)

现有的查询对我来说非常好,虽然可以稍微简化一下:

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

- 因为如果a.AreaID和e.AreaID都为空,则条件dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaID不会评估为真。

(括号不是严格要求的,但为了清楚起见包括在内。)

答案 1 :(得分:2)

对我来说是正确的;你的逻辑和方法看起来很合理。

尽管AND / OR的组合可能会被误解......也许考虑将你的AND表达式括在括号中(我知道这是多余的,但这样做可以澄清你的意图)。根据@MarkBannister最近的回答,这可能会揭示布尔代数分解的机会: - )

我个人将内部联接的ON子句中的任何“过滤”移动到WHERE子句中,只留下与连接本身相关的表达式,如果只有一个连接并且这些过滤器与连接逻辑本身。但这不是这种情况。

索引可能会影响这种方式或其他方式...检查您的执行计划,看看您是否可以在FK或文本字段中添加一些内容。

答案 2 :(得分:1)

我认为你不需要不为空 如果AreaID为null,则dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaID将评估为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