我写了这个查询来查找任何月份最后一天的订单。
我知道如果对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);
答案 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