14

私はSQLServerの機器/資産データベースのかなり複雑な側面に取り組んでいます。助けを求めたいと思います。ここでは1つの問題に焦点を当ててから、別の問題について別の質問をします。

と呼ばれる機器の表と、機器tblEquipmentのコレクションに対して実行する必要のある必要なアクションの表(tblActionsRequired)があります。この質問のために、関連するフィールドは次のとおりです。

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

つまり、tblRequiredActionsサイトAのすべての機器を頻繁に検査する必要があるということです。エリアとは、サイト内の特定の部屋やオフィスなどです。したがって、AllSitesがtrueの場合、アクションは全社的なすべての機器に適用されます。falseの場合、BasedAtID(サイト用)が必要です。さらに絞り込む場合は、AreaIDはオプションです。

では、これら3つのフィールドに基づいて、どのアクションをどの機器に適用するかを抽出するという問題があります。

私が今持っているのはうまくいくと思うものですが、他にも混乱する要因があるため、結果を確認するのに苦労しています。完全に間違った方向に進んでいる場合は、確認またはガイダンスをいただければ幸いです。ストアドプロシージャのルートに行きたくありません。同様の原則でカバーする必要のある他の複数のディメンションがあるため、ブロックまたはユニオンの場合、維持するのは悪夢となる非常に複雑なプロシージャを作成することになります。 。ありがとう!!

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の両方がnullの場合、条件dbo.tblEquipment.AreaID = dbo.tblActionsRequired.AreaIDはtrueと評価されないためです。

(括弧は厳密には必須ではありませんが、わかりやすくするために含まれています。)

于 2013-03-27T14:25:45.350 に答える
2

私には正しいように見えます。あなたの論理とアプローチは健全に見えます。

AND / ORの組み合わせは誤解を招く可能性がありますが、おそらくAND式を括弧で囲むことを検討してください(これは冗長であることはわかっていますが、そうすることで意図が明確になります)。そして、@ MarkBannisterの最近の回答によると、これはブール代数因数分解の機会を明らかにするかもしれません:-)

結合が1つだけで、それらのフィルターが結合ロジックから分離されている場合は、個人的に「フィルタリング」を内部結合のON句からWHERE句に移動し、結合自体に関連する式だけを残します。自体。しかし、これはここでは当てはまりません。

インデックスはおそらくこれに何らかの影響を及ぼします...実行プランをチェックして、FKまたはテキストフィールドにインデックスを追加することでメリットが得られるかどうかを確認してください。

于 2013-03-27T14:15:33.540 に答える
1

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 に答える