2012-03-19 140 views
2

我想写一个选择查询,其中我的OrderDate是两个月之间。 这是我的代码到目前为止。两个月之间选择

declare @FromMonth datetime 
declare @ToMonth datetime 
set @FromMonth = '20111201' 
set @ToMonth = '20120301' 

select * 
from Order o 
where o.OrderDate between @FromMonth and @ToMonth 

这几乎工作,但它也着眼于一个月的一天,在这个例子中这意味着它不会选择我@ToMonth所有的日子

我使用SQL Server 2012

编辑

只是为了更清楚,我不想我的信任和@FromMonth输入@ToMonth知道最后一天的月份。以上只是一个例子来说明我的问题。

+0

确实,你需要什么? – 2012-03-19 09:41:49

+0

你试过这个吗? - > set @ToMonth ='20120331' – Zohaib 2012-03-19 09:43:10

+0

这是因为你的日期时间有一个日期,而你没有指定你只想要BETWEEN关心年和月......尝试使用MONTH()和YEAR()函数,或者设置你的月份到月份的最后一天 – 2012-03-19 09:44:36

回答

4

between很少奏效,以及你可能希望,我通常会发现它更好地写范围为一个包容性/排他性对,并采取适当的对比:

declare @FromMonth datetime 
declare @ToMonth datetime 
set @FromMonth = '20111201' 
set @ToMonth = '20120401' 

select * 
from Order o 
where o.OrderDate >= @FromMonth and o.OrderDate < @ToMonth 

这也将避免污秽如果OrderDate包括时间分量。

+0

+1用于指示OP使用' = X和 MatBailie 2012-03-19 09:56:24

+0

就像你简单的解决方案一样,尽管我觉得它有点作弊,你改变@ToMonth输入,会看一看如果我可以让我的代码的其余部分与它一起工作。 – gulbaek 2012-03-19 10:06:30

+2

@gulbaek - 这不是作弊,它正在修复。您的输入是DATETIME,一个*连续*值。 '20120301'并不意味着“三月一日”,这意味着“三月一日的00:00”。 “BETWEEN”适用于整数等离散值。使用'> ='和'<'作为连续值。如果该字段是FLOAT,则不会期望'WHERE my_float BETWEEN 1 AND 2'包含'2.9'。为此,你应该说'WHERE my_float> = 1 AND my_float <3'。同样,就你的情况而言,如果你只需要一个月,你的参数都是'20120101',但这些值之间没有时间。使用'<'可以让这变得更有意义。 – MatBailie 2012-03-19 10:12:29

1

更改您的WHERE子句类似:

WHERE (MONTH(o.OrderDate) BETWEEN MONTH(@FromMonth) AND MONTH(@ToMonth)) 
AND (YEAR(o.OrderDate) BETWEEN YEAR(@FromMonth) AND YEAR(@ToMonth)) 
+0

这将破坏优化程序使用索引的机会有效。要解决此查询需要全面扫描,而不是寻求更快。 – MatBailie 2012-03-19 09:58:57

2

首先DATEADD/DATEDIFF对返回月份的第一天,第二次返回下个月的第一天:

where o.OrderDate >= dateadd(m, datediff (m, 0, @FromMonth), 0) 
    and o.OrderDate < dateadd(m, datediff (m, 0, @ToMonth) + 1, 0) 

编辑:改变了我的回应根据德姆的建议。

+0

如果订购日期有时间部分,该怎么办?每月最后一天早上00:00后的任何内容都会被忽略。见@ Damien_The_Unbeliever的答案;使用'> =和<'来获得连续值。 “BETWEEN”只能用于离散值。 – MatBailie 2012-03-19 09:58:07

+0

谢谢@Dems。我相应地编辑了我的回复。 – 2012-03-19 10:04:56

+0

+1,因为这个现在可以工作,我不希望它夹在错误的流水线:) – MatBailie 2012-03-19 10:19:19

0
WHERE MONTH(*col name*) between'01' and '05' 

这会给数据B/W 1月至5和山坳名应该是日期列。