如何在条件下正确使用AND / OR

时间:2018-09-12 02:26:59

标签: sql-server tsql

我有一个类似这样的查询:

SELECT AVG([DC].[ContractedAmount]) AS [AverageContractedAmount]
      ,MAX([DC].[ContractedAmount]) AS [MaxContractedAmount]
      ,MIN([DC].[ContractedAmount]) AS [MinContractedAmount]
FROM [DesignCustomer] AS [DC]
INNER JOIN [Design] AS [D] ON [DC].[DesignKey] = [D].[DesignKey]
INNER JOIN [Task] AS [T] ON [D].[DesignKey] = [t].[DesignKey]
INNER JOIN [ProjectDesign] AS [PD] ON [D].[DesignKey] = [PD].[DesignKey]
INNER JOIN [Project] AS [P] ON [PD].[ProjectKey] = [P].[ProjectKey]
INNER JOIN [Address] AS [A] ON [A].[AddressGuid] = [P].[ProjectGuid]
WHERE [DC].[ContractedAmount] != 0.00
AND [DC].[CustomerKey] = @CustomerKey
OR [A].[RegionKey] = @RegionKey
OR [A].[StateKey] = @StateKey

由于某种原因,当我执行它[MinContractedAmount]返回0.00的值时,它不在乎我的where子句[DC].[ContractedAmount] != 0.00,为什么它不起作用?

注意[DC].[ContractedAmount]是一个金钱字段

3 个答案:

答案 0 :(得分:7)

您需要在()子句中使用WHERE,因为AND运算符具有优先权,现在解释器可以理解

WHERE ([DC].[ContractedAmount] != 0.00 AND [DC].[CustomerKey] = @CustomerKey)
 OR [A].[RegionKey] = @RegionKey
 OR [A].[StateKey] = @StateKey

您可能想要

WHERE [DC].[ContractedAmount] != 0.00 
  AND ( [DC].[CustomerKey] = @CustomerKey
     OR [A].[RegionKey] = @RegionKey
     OR [A].[StateKey] = @StateKey )

答案 1 :(得分:0)

您需要了解ANDOR的工作原理。

AND的结果为TRUE 仅在所有涉及的条件为TRUE

ORTRUE的结果即使只是其中之一,涉及的条件是TRUE

这说明了您注意到某个条件被忽略的行为。

返回TRUE

condition1 = TRUE AND condition2 = TRUE

返回TRUE:

condition1 = FALSE AND condition2 = FALSE OR condition3 = TRUE

解决方案:使用括号将只需要1个结果为TRUE的条件分组。

返回FALSE

(condition1 = TRUE OR condition2 = TRUE) AND condition3 = FALSE

答案 2 :(得分:0)

如果我理解,您想要这个:

SELECT AVG(DC.ContractedAmount) AS AverageContractedAmount
      ,MAX(DC.ContractedAmount) AS MaxContractedAmount
      ,MIN(DC.ContractedAmount) AS MinContractedAmount
FROM DesignCustomer AS DC
WHERE DC.ContractedAmount <> 0 AND DC.CustomerKey = @CustomerKey
and exists
(
    select * 
    from Design AS D
    INNER JOIN Task AS T ON D.DesignKey = t.DesignKey
    INNER JOIN ProjectDesign AS PD ON D.DesignKey = PD.DesignKey
    INNER JOIN Project AS P ON PD.ProjectKey = P.ProjectKey
    INNER JOIN Address AS A ON A.AddressGuid = P.ProjectGuid and (A.RegionKey = @RegionKey or A.StateKey = @StateKey)
    where DC.DesignKey = D.DesignKey
)