如何在SQL Server中有效地使用AND / OR

时间:2017-02-02 13:34:21

标签: sql sql-server

我是编程新手,这是我的第一个问题,所以如果我犯了错误,我会道歉。

我写了这个查询:

   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%'

我想指定四件事:

1)我得到的结果来自英国

2)我得到的结果包含我在'LIKE'参数中指定的任何单词。

3)结果符合规则(UWHT.Id = 1,USI.Id = 1)。

4)只有过去5年的StartDate结果才会返回给我。

除了地点外,没有其他任何东西可以按照我的意愿返回。我想这是因为不正确的AND / OR语法,但是找不到以前的SO问题解释如何做到这一点(如果有的话我错过了,我道歉)。

2 个答案:

答案 0 :(得分:1)

我看到错误的第一件事是你在where子句中的任何地方都没有使用parens。您希望将OR s与其关联的AND s:

分组
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.00美元?"

除了我刚才说明的那些之外,还有一些解释。 SQL Server有规则,因此它总是根据特定的操作顺序进行解释,这可能不一定很清楚,从而导致错误。为了克服这个问题,你使用parens来强制它以某种方式解释:

"你能给我一份1.)在奶牛岛或冷冻食品岛上的商品清单,以及2.)价格低于3.00美元或高于7.00美元的商品吗?"

答案 1 :(得分: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%'
    )
);