14

我正在研究 SQL Server 中设备/资产数据库的一个相当复杂的方面,并希望寻求帮助。我将在这里尝试专注于一个问题,然后针对另一个问题提出一个单独的问题。

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

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

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

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

我现在所拥有的是我认为可能有效的方法,但我正在努力验证我的结果,因为还有其他因素也让我感到困惑,所以如果我完全走错了路,我真的很感激一些确认或指导!我不想走存储过程和 if 块或联合的路线,因为还有多个其他维度需要用类似的原则来覆盖,我最终会编写一个非常复杂的过程,这将是一场噩梦. 谢谢!!

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
4

3 回答 3

7

现有的查询对我来说看起来不错,尽管可以稍微简化一下:

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不会评估为真。

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

于 2013-03-27T14:25:45.350 回答
2

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

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

我会亲自将任何“过滤”从内部连接的 ON 子句中移到 WHERE 子句中,只留下与连接本身相关的表达式,在只有一个连接并且这些过滤器与连接逻辑隔离的情况下本身。但这里不是这种情况。

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

于 2013-03-27T14:15:33.540 回答
1

我认为您不需要 not null
如果 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
于 2013-03-27T14:24:49.020 回答