使用sargable查询查找任何月份最后一天的订单?

时间:2014-02-04 15:46:30

标签: sql sql-server sql-server-2008

我写了这个查询来查找任何月份最后一天的订单。

我知道如果对orderdate编制索引,则不建议使用此方法。我应该采用什么方法来使其成为可耻的?

select o.orderid, o.orderdate, o.custid, o.empid
from  sales.Orders o
where day(o.orderdate) in (30, 31) 
         or (month(o.orderdate) = 02 and day(o.orderdate)= 28) 
         or (month(o.orderdate) = 02 and day(o.orderdate)= 29);

6 个答案:

答案 0 :(得分:2)

您可以使用计算列执行此操作:

alter table Orders add column nextdayofmonth as day(dateadd(day, 1, orderdate));

create index orders_nextdayofmonth on orders(orders_nextdayofmonth);

下一天是下一个日,因此可以轻松处理闰年。毕竟,“最后一天”之后的第二天是下个月的“第一天”。

然后将您的查询短语为:

where next_dayofmonth = 1

这个表达是可以理解的。

答案 1 :(得分:1)

DATEADD是可以理解的:

WHERE DATEADD(day, DATEDIFF(day, 0, o.orderdate), 0) = 
      DATEADD(day, -1, DATEADD(month, DATEDIFF(month, 0, o.orderdate) + 1, 0)) 

第一种方法是从datetime截断时间的旧方法。第二个增加一个月,“截断”月份并减去一天。

Here's一个小提琴,以相同的“技巧”返回当月的最后一天。

答案 2 :(得分:0)

此查询将在闰年失败,因为它会在2月份为您提供2个日期作为该月的最后一天。要使其成为SARGable,您需要取出日期列中的函数。

答案 3 :(得分:0)

这应该可以正常工作

select o.orderid, o.orderdate, o.custid, o.empid
from  sales.Orders o
where
day(o.orderdate)=day(DATEADD(ms, -3, DATEADD(mm, DATEDIFF(m, 0,o.orderdate) + 1, 0)))

以下查询给出了当月的最后一天,将getdate()替换为日期变量,如上所示:

SELECT day(DATEADD(ms, -3, DATEADD(mm, DATEDIFF(m, 0, GETDATE()) + 1, 0)))

答案 4 :(得分:0)

你也可以这样做:

select TOP 1 orderid, orderdate, custid, empid
from  sales.Orders 
ORDER BY orderdate DESC

答案 5 :(得分:0)

获取明天DAY部分为1的所有日期:

SELECT *
FROM Sales.Orders
WHERE DAY(DATEADD(dd, 1, orderdate)) = 1