MSSQL WHERE YEAR 子句返回所有日期而不是指定日期[关闭]
Posted
技术标签:
【中文标题】MSSQL WHERE YEAR 子句返回所有日期而不是指定日期[关闭]【英文标题】:MSSQL WHERE YEAR clause returning all dates instead of date specified [closed] 【发布时间】:2020-12-11 10:49:29 【问题描述】:这里没有人帮助我,但互联网的空白和我的谷歌搜索技能充其量是平庸的。
下面的语法返回我需要的信息,但是它给了我表中的所有日期并忽略了 WHERE 子句。我正在尝试加入 3 个表:“ProductHistory”是主要表,“Product”需要一列,第三个表“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
我在第一个语句中哪里错了?
非常感谢您的帮助。
【问题讨论】:
为什么要使用MONTH
和YEAR
?使用正确的日期逻辑:Yourdate >= '20200501' AND YourDate < '20200601'
。由于查询将是 SARGable,因此性能要好得多。
当您在不使用括号的情况下混合AND
和OR
时,您必须检查优先规则以确定它们如何组合。我建议您插入适当的括号,以明确其他条件在 Type
为 6 时也适用。
【参考方案1】:
将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
您可以看到,这允许任何具有 Type 6 的产品,而不管其他条件如何。
我还建议进一步优化:
在日期上使用直接过滤而不是应用日期函数而不是存储值 - 这要高效得多
使用IN
代替OR
ed 条件
所以:
WHERE
[MainJobDetails].[DespatchDate] >= '20201101'
AND [MainJobDetails].[DespatchDate] < '20201201'
AND [ProductHistory].[Type] IN (5, 6)
【讨论】:
啊!当然,我没有使用 >= 这成功了!并且数据加载速度更快。非常感谢。如果没有这个论坛,我不知道我会做什么。以上是关于MSSQL WHERE YEAR 子句返回所有日期而不是指定日期[关闭]的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 pypyodbc 在 python 中使用 where 子句运行 mssql 选择查询
MSSQL - 在 where 和 on 子句性能上添加条件
MySQL 中基于 MSSQL 语法按 YEAR 选择日期范围的等效语法是啥?