MSSQL WHERE YEAR 子句返回所有日期而不是指定的日期

MSSQL WHERE YEAR clause returning all dates instead of date specified

这里是初级,没有人帮助我,但互联网的空白和我的谷歌搜索技能充其量只是平庸。

以下语法 returns 是我需要的信息,但是它在 table 中为我提供了所有日期并忽略了 WHERE 子句。我正在尝试加入 3 个 table:'ProductHistory' 是主要的,'Product' 需要一列,第三个 table 需要一个日期字段 'MainJobDetails'.

SELECT [ProductHistory].[Type]
    ,[ProductHistory].[Ref]
    ,[ProductHistory].[JobNo]
    ,[ProductHistory].[Quantity]
    ,[ProductHistory].[PurchasePrice]
    ,[ProductHistory].[UnitPrice]
    ,[ProductHistory].[UnitDesc]
    ,[ProductHistory].[ProductID]
    ,[ProductHistory].[Location]
    ,[ProductHistory].[UserID]
    ,[Product].[Description]
    ,[Product].[StkRef1]
    ,[MainJobDetails].[DespatchDate]
FROM [ProductHistory]
JOIN [Product] ON [ProductHistory].[ProductID] = [Product].[ID]
JOIN [MainJobDetails] ON [ProductHistory].[JobNo] = [MainJobDetails].[JobNo]
WHERE YEAR([MainJobDetails].[DespatchDate]) = 2020
AND MONTH([MainJobDetails].[DespatchDate]) = 11
AND [ProductHistory].[Type] = 5
OR [ProductHistory].[Type] = 6
ORDER BY [MainJobDetails].[DespatchDate] DESC

我尝试将 WHERE 子句更改为:

WHERE [MainJobDetails].[DespatchDate] BETWEEN '2020/10/31' AND '2020/11/30'

但这没有什么区别。

这是我之前使用过的另一个类似查询,它运行良好:

SELECT [MainJobDetails].[JobNo]
      ,[MainJobDetails].[EstimateHeaderRef]
      ,[MainJobDetails].[InvoiceCustomerName]
      ,[MainJobDetails].[JobDesc]
      ,[MainJobDetails].[DespatchDate]
      ,[FinishingInput].[Code]
      ,[FinishingInput].[Description]
      ,[FinishingInput].[Runs]
      ,[FinishingInput].[Timedb] 
  FROM [MainJobDetails]
  LEFT JOIN [FinishingInput]
  ON [MainJobDetails].[EstimateHeaderRef]=[FinishingInput].[EstimateHeaderRef]
  WHERE [MainJobDetails].[DespatchDate] BETWEEN '2020/11/01' AND '2020/12/31'
  ORDER BY [MainJobDetails].[DespatchDate] DESC

我在第一句话中犯了什么错误?

非常感谢您的帮助。

OR条件放在括号内:

WHERE 
    YEAR([MainJobDetails].[DespatchDate]) = 2020
    AND MONTH([MainJobDetails].[DespatchDate]) = 11
    AND ([ProductHistory].[Type] = 5 OR [ProductHistory].[Type] = 6)
      --^-- here                                        and here --^-- 

为什么需要它是因为 OR 在逻辑表达式中的优先级低于 AND。所以你的原始代码(没有括号)相当于:

WHERE 
    (
        YEAR([MainJobDetails].[DespatchDate]) = 2020
        AND MONTH([MainJobDetails].[DespatchDate]) = 11
        AND ([ProductHistory].[Type] = 5
    )
    OR [ProductHistory].[Type] = 6

您可以看到,无论其他条件如何,这都允许任何类型 6 的产品。

我还建议进一步优化:

  • 在日期上使用直接过滤而不是应用日期函数而不是存储值 - 这样 很多 更有效

  • 使用 IN 而不是 ORed 条件

所以:

WHERE 
        [MainJobDetails].[DespatchDate] >= '20201101'
    AND [MainJobDetails].[DespatchDate] <  '20201201'
    AND [ProductHistory].[Type] IN (5, 6)