Как правильно использовать И / ИЛИ в условиях - PullRequest
0 голосов
/ 12 сентября 2018

У меня есть запрос вроде этого:

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 голосов
/ 12 сентября 2018

Вам нужно понять, как работает AND и OR.

AND результаты до TRUE ТОЛЬКО ЕСЛИ ВСЕ задействованные условия TRUE

OR приводит к TRUE ДАЖЕ ЕСЛИ ТОЛЬКО ОДИН ИЗ условия участия 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

0 голосов
/ 12 сентября 2018

Если я понимаю, вы хотите это:

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
)
0 голосов
/ 12 сентября 2018

Вам необходимо использовать () для предложения 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 )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...