2017-02-02 6 views
3

私はプログラミングの初心者です。これは私の最初の質問です。間違えた場合はお詫び申し上げます。SQL ServerでAND/ORを効果的に使用する方法

私はこのクエリ書かれている

SELECT U.Id, UWH.Role, USI.Title, CAST(USI.StartDate AS DATE) 
    FROM UserWorkHistory UWH 
    JOIN Users U ON UWH.UserId=U.Id 
    JOIN UserStoryItems USI ON U.Id=USI.UserId 
    JOIN UserWorkHistoryTypes UWHT ON UWH.UserWorkHistoryTypeId=UWHT.Id 
    WHERE U.Location LIKE '%Great Britain%' 
     OR U.Location LIKE '%United Kingdom%' 
     OR U.Location LIKE '%England%' 
     OR U.Location LIKE '%UK%' 
     OR U.Location LIKE '%U.K.%' 
     AND UWHT.Id = 1 
     AND USI.Id = 1 
     AND CAST(USI.StartDate AS DATE) > DATEADD(YEAR,-5,GETDATE()) 
     AND UWH.Role LIKE '%Contract%' 
     OR UWH.Role LIKE '%Contractor%' 
     OR UWH.Role LIKE '%Freelance%' 
     OR UWH.Role LIKE '%Non-perm%' 
     OR UWH.Role LIKE '%non-permanent%' 
     OR USI.Title LIKE '%Contractor%' 
     OR USI.Title LIKE '%Contractor%' 
     OR USI.Title LIKE '%Freelance%' 
     OR USI.Title LIKE '%Non-perm%' 
     OR USI.Title LIKE '%non-permanent%' 
     OR USI.Title LIKE '%self-made%' 

私は4つの物事を指定しようとしています:私は戻って取得結果は、英国

2)の結果それからのものであること

1)私は 'LIKE'引数で指定した単語のどれかを返します。

3)結果がルールに従うこと(UWHT.Id = 1、USI.Id = 1)。

4)過去5年間のStartDateの結果のみが返されます。

私が望むように、場所以外は何も戻っていません。私はそれが誤ったAND/OR構文のためだと思いますが、これを行う方法を説明している以前のSOの質問を見つけることができません(もしあれば、私はそれを逃しました、私は謝ります)。

+3

可能な重複[SQLロジック演算子の優先順位:ANDとOR](http://stackoverflow.com/questions/1241142/sql-logic-operator-precedence-and -and-or) –

+1

あなたのクエリにはカッコが必要です。 – jarlh

+1

また、位置文字列、役割、タイトルをLIKEでJOINすることで、クエリが簡単になり、クエリー自体を変更することなく追加/削除が容易になります。 –

答えて

1

最初に間違っているのは、where句のどこにでも括弧を使用していないということです。あなたはそれに関連するANDの持つグループにOR秒をしたい:

WHERE 
    (U.Location LIKE '%Great Britain%' 
    OR U.Location LIKE '%United Kingdom%' 
    OR U.Location LIKE '%England%' 
    OR U.Location LIKE '%UK%' 
    OR U.Location LIKE '%U.K.%') 
AND UWHT.Id = 1 
AND USI.Id = 1 
AND CAST(USI.StartDate AS DATE) > DATEADD(YEAR,-5,GETDATE()) 
AND 
    (UWH.Role LIKE '%Contract%' 
    OR UWH.Role LIKE '%Contractor%' 
    OR UWH.Role LIKE '%Freelance%' 
    OR UWH.Role LIKE '%Non-perm%' 
    OR UWH.Role LIKE '%non-permanent%' 
    OR USI.Title LIKE '%Contractor%' 
    OR USI.Title LIKE '%Contractor%' 
    OR USI.Title LIKE '%Freelance%' 
    OR USI.Title LIKE '%Non-perm%' 
    OR USI.Title LIKE '%non-permanent%' 
    OR USI.Title LIKE '%self-made%') 

理由は、操作の順序があるということです。もっと簡単な例を挙げましょう。もし誰かに尋ねたいのであれば、「あなたは、酪農場にいるか、冷凍食品の中にいて、$ 3.00以下の費用がかかります$ 7.00を超える?

その意味はあいまいです。例えば、あなたは、「酪農島(価格は関係ありません)にあるもの、または冷凍食品の島にあるもの(冷凍食品アイテム)は$ 3.00または$ 7.00を下回っていますか?あなたはでもと言います。「酪農島や冷凍食品の島にあるものをリストに入れてもらえますか?3.00ドル以下の費用は7セント以上ですか?

私が今説明したもののほかに、いくつかの解釈があります。 SQL Serverにはルールがあるため、常に特定の操作順序に基づいて解釈されますが、必ずしも明確ではない場合があり、バグが発生します。これを克服するには、括弧を使用して特定の方法で解釈させるようにしてください:

"1.酪農島または冷凍食品園にある1.) $ 3.00または$ 7.00を下回る費用?

+0

質問では、2番目の点によると(私が戻った結果には、 'LIKE'引数で指定した単語は含まれていないので)私はLIKEをNOT LIKEに変更する必要があると思います。 – balaji

+0

華麗な、ありがとう! – BadAtCoding

+0

@balajiあなたは正しいです - 私は実際には同じものを2つ保存して同じものを保存し、同じデータセットから2つの異なる結果を取得しようとします。私はその後、間違ったものをコピーして質問に貼り付けました。元の質問を編集してこれを変更します。良い点! – BadAtCoding

1

AND takes precedence over OR。あなたはグループあなたANDOR文べき:

Select U.Id, 
     UWH.Role, 
     USI.Title, 
     Cast(USI.StartDate As Date) 
From UserWorkHistory  UWH 
Join Users    U On UWH.UserId = U.Id 
Join UserStoryItems  USI On U.Id = USI.UserId 
Join UserWorkHistoryTypes UWHT On UWH.UserWorkHistoryTypeId = UWHT.Id 
Where 
(
    U.Location Like '%Great Britain%' 
Or U.Location Like '%United Kingdom%' 
Or U.Location Like '%England%' 
Or U.Location Like '%UK%' 
Or U.Location Like '%U.K.%' 
) 
And UWHT.Id = 1 
And USI.Id = 1 
And Cast(USI.StartDate As Date) > DateAdd(Year, -5, GetDate()) 
And 
(
    (
     UWH.Role Like '%Contract%' 
    Or UWH.Role Like '%Contractor%' 
    Or UWH.Role Like '%Freelance%' 
    Or UWH.Role Like '%Non-perm%' 
    Or UWH.Role Like '%non-permanent%' 
    ) 
    Or 
    (
     USI.Title Like '%Contractor%' 
    Or USI.Title Like '%Contractor%' 
    Or USI.Title Like '%Freelance%' 
    Or USI.Title Like '%Non-perm%' 
    Or USI.Title Like '%non-permanent%' 
    Or USI.Title Like '%self-made%' 
    ) 
); 
+0

これははるかに理にかなっています、ありがとう! – BadAtCoding

+0

@Siyualと同様に、Transact-SQLの演算子の優先順位を理解する必要があります。 https://msdn.microsoft.com/en-us/library/ms189773.aspxおよびhttps://msdn.microsoft.com/en-us/library/ms190276.aspxを参照してください。細かい制御のためにかっこを使用してください。最良のアドバイス、where句をビットごとにコーディングすると、AND演算子とOR演算子がどのように動作するかをすぐに知ることができます。 – Steve

関連する問題