我实际上已经解决了问题,但是我试图理解为什么会发生此问题,因为据我所知,没有理由发生此问题。 我有一个相当大的查询,可以运行以准备一些常用组合的表。通常,它仅包含2年的数据。有时我会重建它。在执行此操作时,我对查询进行了调整以添加更多信息,但是突然结果不再与旧查询匹配。将新旧版本进行比较,我注意到一些缺失的订单。令人惊讶的是,即使删除了经过调整的部分,结果仍然不匹配。
我最终将问题追溯到我的WHERE子句,这与我上次的处理方式不同。
我要查看的orderdate列的类型为(datetime,null)
其中一个被省略的订单的日期为:
2018-12-23 20:58:52.383
其中包含的订单的日期为:
2019-01-28 15:20:49.107
对我来说看起来完全一样。
除了WHERE子句外,整个查询是相同的。我原来的位置是:
WHERE DATEPART(yyyy,tbOrder.[OrderDate]) >= DATEPART(yyyy,GETDATE()-2)
我现在的新位置:
WHERE tborder.[OrderDate] >= DATEADD(yy, DATEDIFF(yy, 0, GETDATE())-2, 0)
对于理解为什么原始的where子句删除某些行的任何帮助,将不胜感激。
答案 0 :(得分:0)
因为您正在做两种不同的事情。第一个谓词
WHERE DATEPART(yyyy,tbOrder.[OrderDate]) >= DATEPART(yyyy,GETDATE()-2)
取所有大于前一天或前两天的年份的订单日期。请注意,-2
在方括号内。
第二个谓词
WHERE tborder.[OrderDate] >= DATEADD( yy, DATEDIFF( yy, 0, GETDATE() ) - 2, 0)
取所有大于两年前的订单日期,即datediff(yy,startdate,enddate)
将返回今天与date
数据类型的初始值(1900-01-01
)之间的差值的年份结果。然后,将-2
添加到1900-01-01
。第二个表达式的形式为:
1900 +(201X-1898)
我简化了1900-2 = 1898。
答案 1 :(得分:0)
这两个表达式返回的结果完全不同,因此结果不同也就不足为奇了。第一个以数字形式返回 current 年(准确地说是前一天的年份)。第二个返回两年前的1月1日。
您可以将两个表达式都放在SELECT查询中,以查看它们返回的内容:
select DATEPART(yyyy,GETDATE()-2), DATEADD(yy, DATEDIFF(yy, 0, GETDATE()) - 2, 0)
结果是:
2019 2017-01-01 00:00:00.000
两个表达式都比它们需要的复杂。 first 条件也会损害性能,因为DATEPART(yyyy,tbOrder.[OrderDate])
阻止服务器使用覆盖OrderDate
的任何索引。
该问题并未说明您实际要返回的内容。如果您想返回当年的所有行,可以使用:
Where
OrderDate >=DATEFROMPARTS( YEAR(GETDATE()) ,1,1) and
OrderDate < DATEFROMPARTS( YEAR(GETDATE()) + 1,1,1)
同样可以用来查找过去两年的行:
Where
OrderDate >= DATEFROMPARTS( YEAR(GETDATE()) -2 ,1,1) and
OrderDate < DATEFROMPARTS(YEAR(GETDATE()) - 1,1,1)
两年前1月1日以来的所有行:
Where OrderDate >= DATEFROMPARTS( YEAR(GETDATE()) -2 ,1,1)
所有这些查询都可以利用覆盖OrderDate
的索引。
日期范围查询将变得更容易很多。日历表是一个表,其中包含例如50或100年的日期,并带有月份,月份,星期几,星期几,季度,学期,月份和日期名称,假期,业务重复期,格式短的额外列,长约会等
这使年度,每月或每周查询与加入“日历”表并根据所需的月份或期间进行过滤一样容易。
在这种情况下,过去两次检索行看起来像:
From Orders inner Join Calendar on OrderDate=Calendar.Date
Where Calendar.Year=YEAR(GETDATE())-2
这看起来可能并不令人印象深刻,但是两年前的第二季度呢?
From Orders inner Join Calendar on OrderDate=Calendar.Date
Where Calendar.Year=YEAR(GETDATE())-2 and Quarter=2
两年前,同一季度
From Orders inner Join Calendar on OrderDate=Calendar.Date
Where Calendar.Year=YEAR(GETDATE())-2 and Quarter=DATEPART(q,GETDATE())
检索过去两年中当前季度的总计:
SELECT Year,Quarter,SUM(Total) QuarterTotal
From Orders inner Join Calendar on OrderDate=Calendar.Date
Where Calendar.Year > YEAR(GETDATE())-2 and Quarter=DATEPART(q,GETDATE())
GROUP BY Calendar.Year