我之前遇到过这个问题,但从未真正弄清楚问题是什么。我希望你们中的一位大师帮助解释什么会导致WHERE子句被忽略。大图片问题是:
当忽略WHERE子句时,哪里是开始寻找的最佳位置?
通常会导致此问题的原因是什么?
在这种特定情况下,我尝试过滤掉某些服务代码。我尝试过使用NOT LIKE子句,或者只是使用IN()子句将我想要的服务代码列入白名单,但无论如何都要完全忽略该语句。每个服务代码也与服务类相关联,并使用这些相同的运算符来过滤掉所需的服务类或将其列入白名单。我已经尝试将NOT LIKE和IN子句移动到我的WHERE下的第一个标准,如果它是一个操作顺序问题,并且我在某处检查了缺失的括号。因此,此查询返回的结果没有任何错误消息,但它不会过滤掉不需要的行。
查询很乱,因为每个发票都有5个不同的字段,TechID可以在其中,每个字段表示不同的字段,但这里是查询:
{{1}}
非常感谢任何建议或咨询。谢谢!
答案 0 :(得分:1)
没有任何情况会导致整个where子句被忽略。可能发生的事情是你的where子句在OR的任一侧有表达式,如果一方评估为true,那么另一方并不重要。当你将许多AND和OR组合在一起时,你必须非常小心你的括号。
答案 1 :(得分:1)
以下是您的查询的重新格式,我已经标记了我认为您的or
出现故障的位置。
select
Location = (select LocationCode
from Locations
where Invoices.Locationid = Locations.Locationid)
, Invoices.OrderNum
, Invoices.ServiceCode
, Invoices.WorkDate
, Invoices.Total
/* , ServiceClass = Classes.Code */
, Tech = (select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid1)
, Helper = (select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid2)
, 'Sales Blue 1' = (select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid3)
, 'Sales Blue 2' = (select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid4)
, 'Term Self' = (select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid5)
, 'Sales Rep' = case
when /* self Gen */ Invoices.Techid5 in ('298', '194', '330', '391', '335')
then (
select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid5)
when /* Sales Blue 2 */ Invoices.Techid4 in ('298', '194', '330', '391', '335')
then (
select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid4)
when /* Sales Blue 1 */ Invoices.Techid3 in ('298', '194', '330', '391', '335')
then (
select Employees.Username
from Employees
where Employees.TechId = Invoices.Techid3)
end
, Sale status = case
when /* self Gen */ Invoices.Techid5 in ('298', '194', '330', '391', '335')
then 'Self-Gen'
when /* Sales Blue 2 */ Invoices.Techid4 in ('298', '194', '330', '391', '335')
then 'bsp Lead 2'
when /* Sales Blue 1 */ Invoices.Techid3 in ('298', '194', '330', '391', '335')
then 'bsp Lead'
else 'Error'
end
from Employees Employees
inner join Invoices Invoices on Employees.Techid = Invoices.Techid3
inner join Services Services on Invoices.ServiceCode = Services.Code
inner join Classes Classes on Services.Classid = Classes.Classid
where /* Brian is 298, Cindy is 194, Jeremiah is 330, Monty is 391, and Tom is 335. */
/* Technician and Sales Rep */
Invoices.ServiceCode in ('bed bug chem co', 'bed bug chem')
and (
Invoices.Techid1 in ('298', '194', '330', '391', '335')
and Invoices.Techid3 in ('298', '194', '330', '391', '335')
or Invoices.Techid5 in ('298', '194', '330', '391', '335')
) /* Sales Blue 1 , Sold but bspc Lead */
/* ----------------------------------------------- */
/* do these 'or's belong somewhere else? */
or Invoices.Techid3 in ('298', '194', '330', '391', '335') /* Sales Blue 2 */
or Invoices.Techid4 in ('298', '194', '330', '391', '335') /* Term self (Gen) */
or Invoices.Techid5 in ('298', '194', '330', '391', '335')
/* ----------------------------------------------- */
and (
Invoices.WorkDate <= GetDate()
and year(Invoices.WorkDate) = year(GetDate())
)
and Invoices.ServiceCode not like 'eom%'
and Invoices.ServiceCode not like 'eom1%'
and Invoices.ServiceCode not like 'M_%'
and Invoices.ServiceCode not like 'M1%'
and Invoices.ServiceCode not like 'Q_%'
and Invoices.ServiceCode not like 'Q1__%'
/* and Classes.Code not in ('eom', 'quarterly', 'monthly') */
order by Sales Rep, Sale status
答案 2 :(得分:0)
试试这个:
SELECT
Locations.LocationCode AS [Location],
Invoices.OrderNum,
Invoices.ServiceCode,
Invoices.WorkDate,
Invoices.Total,
-- Classes.Code AS ServiceClass,
Tech.Username AS Tech,
Helper.Username AS Helper,
SB1.Username AS [Sales Blue 1],
SB2.Username AS [Sales Blue 2],
TS.Username AS [Term Self],
CASE
WHEN --Self Gen
Invoices.TechID5 IN (
298,194,330,391,335)
THEN TS.Username
ELSE
CASE WHEN --Sales Blue 2
Invoices.TechID4 IN (
298,194,330,391,335)
THEN SB2.Username
ELSE
CASE WHEN --Sales Blue 1
Invoices.TechID3 IN (
298,194,330,391,335)
THEN SB1.Username
END
END
END
AS [Sales Rep],
CASE WHEN --Self Gen
Invoices.TechID5 IN (
298,194,330,391,335)
THEN 'Self-Gen'
ELSE
CASE WHEN --Sales Blue 2
Invoices.TechID4 IN (
298,194,330,391,335)
THEN 'BSP Lead 2'
ELSE
CASE WHEN --Sales Blue 1
Invoices.TechID3 IN (
298,194,330,391,335)
THEN 'BSP Lead'
ELSE 'Error'
END
END
END AS [Sale Status]
FROM Employees
INNER JOIN Invoices
ON Employees.TechID = Invoices.TechID3
INNER JOIN [Services]
ON Invoices.ServiceCode = [Services].Code
INNER JOIN Classes
ON [Services].ClassID = Classes.ClassID
INNER JOIN Locations
ON Invoices.LocationID = Locations.LocationID
-- Brian is 298, Cindy is 194, Jeremiah is 330, Monty is 391, and Tom is 335.
-- Technician AND Sales Rep
INNER JOIN Employees Tech
ON Tech.TechID = Invoices.TechID1
INNER JOIN Employees Helper
ON Helper.TechID = Invoices.TechID2
INNER JOIN Employees SB1
ON SB1.TechID = Invoices.TechID3
INNER JOIN Employees SB2
ON SB2.TechID = Invoices.TechID4
INNER JOIN Employees TS
ON TS.TechID = Invoices.TechID5
WHERE
Invoices.ServiceCode IN (
'BED BUG CHEM CO',
'BED BUG CHEM'
)
AND Invoices.WorkDate <= GetDate()
AND YEAR (Invoices.WorkDate) = YEAR (GetDate())
AND Invoices.ServiceCode NOT LIKE 'EOM%'
AND Invoices.ServiceCode NOT LIKE 'EOM1%'
AND Invoices.ServiceCode NOT LIKE 'M_%'
AND Invoices.ServiceCode NOT LIKE 'M1%'
AND Invoices.ServiceCode NOT LIKE 'Q_%'
AND Invoices.ServiceCode NOT LIKE 'Q1__%'
/* AND Classes.Code NOT IN ('EOM', 'QUARTERLY', 'MONTHLY') */
ORDER BY
CASE
WHEN --Self Gen
Invoices.TechID5 IN (
298,194,330,391,335)
THEN TS.Username
ELSE
CASE WHEN --Sales Blue 2
Invoices.TechID4 IN (
298,194,330,391,335)
THEN SB2.Username
ELSE
CASE WHEN --Sales Blue 1
Invoices.TechID3 IN (
298,194,330,391,335)
THEN SB1.Username
END
END
END,
CASE WHEN --Self Gen
Invoices.TechID5 IN (
298,194,330,391,335)
THEN 'Self-Gen'
ELSE
CASE WHEN --Sales Blue 2
Invoices.TechID4 IN (
298,194,330,391,335)
THEN 'BSP Lead 2'
ELSE
CASE WHEN --Sales Blue 1
Invoices.TechID3 IN (
298,194,330,391,335)
THEN 'BSP Lead'
ELSE 'Error'
END
END
END ;
答案 3 :(得分:0)
可能问题在于您的操作顺序,因为在同一查询中使用and和Or时没有正确使用括号。让我分解你的查询的一小部分,你可以看到我的意思
WHERE
-- Brian is 298, Cindy is 194, Jeremiah is 330, Monty is 391, and Tom is 335.
-- Technician AND Sales Rep
"Invoices"."ServiceCode" IN ( 'BED BUG CHEM CO', 'BED BUG CHEM' )
AND ( "Invoices"."TechID1" IN ( '298', '194', '330' '391', '335')
AND "Invoices"."TechID3" IN ( '298', '194', '330' '391', '335')
OR "Invoices"."TechID5" IN ( '298', '194', '330' '391', '335')
)
让我们尝试不同的方式来安排数据,看看你得到的不同价值是什么:
此变体 - 您希望其中一个值同时位于TechID1和TechID3中(但由于它是一个列表,因此它们不必包含相同的值(TechID1 = 298和TechID3 = 194可以使用)除非TechID5包含值,否则您不关心TechID1或TechID3中的值(因此,如果TechID5 = 298,则TechID1等于299,TechID3等于301)
WHERE
-- Brian is 298, Cindy is 194, Jeremiah is 330, Monty is 391, and Tom is 335.
-- Technician AND Sales Rep
"Invoices"."ServiceCode" IN ( 'BED BUG CHEM CO', 'BED BUG CHEM' )
AND ( "Invoices"."TechID1" IN ( '298', '194', '330' '391', '335')
AND "Invoices"."TechID3" IN ( '298', '194', '330' '391', '335'))
OR "Invoices"."TechID5" IN ( '298', '194', '330' '391', '335')
)
在这个变体中,您关心的是这些技术ID是否属于三个领域中的任何一个
WHERE
-- Brian is 298, Cindy is 194, Jeremiah is 330, Monty is 391, and Tom is 335.
-- Technician AND Sales Rep
"Invoices"."ServiceCode" IN ( 'BED BUG CHEM CO', 'BED BUG CHEM' )
AND ( "Invoices"."TechID1" IN ( '298', '194', '330' '391', '335')
OR "Invoices"."TechID3" IN ( '298', '194', '330' '391', '335')
OR "Invoices"."TechID5" IN ( '298', '194', '330' '391', '335')
)
在此变体中,TechID1必须包含其中一个值,其中一个值可以是TechID3或TechID5
WHERE
-- Brian is 298, Cindy is 194, Jeremiah is 330, Monty is 391, and Tom is 335.
-- Technician AND Sales Rep
"Invoices"."ServiceCode" IN ( 'BED BUG CHEM CO', 'BED BUG CHEM' )
AND ( "Invoices"."TechID1" IN ( '298', '194', '330' '391', '335')
AND ("Invoices"."TechID3" IN ( '298', '194', '330' '391', '335')
OR "Invoices"."TechID5" IN ( '298', '194', '330' '391', '335'))
)
在不了解您的业务规则的情况下,我们无法说明哪种变体是正确的。所有都在使用SQL代码。
在您想要混合AND和OR的任何时候使用括号是一个关键的做法,即使操作顺序会给出正确答案,因为在您需要修改查询的六个月内,您不知道是否这是不正确的,或者是否有意。每次使用()时,意图总是清晰的。