我正在为SQL Server中的设备/资产数据库做一个相当复杂的方面,并且想请求一些帮助。我会尝试在这里专注于一个问题,然后针对另一个问题提出单独的问题。
我有一个名为tblEquipment
的设备表和一个需要对设备集合(tblActionsRequired
)执行的操作的表,为了这个问题,相关字段是:< / p>
tblEquipment
:EquipmentID, BasedAtID, AreaID
tblRequiredActions
:AllSites (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
答案 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