2015-02-10 64 views
0

我不能为我的生活得到这个工作。我已经尝试了我在这里和遍布互联网上看到的每一个例子。我试图根据一个月的数据进行查询。在我查询视图中的数据的格式如下:SQL Server:查询条件 - 需要从日期时间提取日期

2012-03-20 00:00:00.000 

使用下列标准这勾起所有的日期(或几乎所有的)。有任何想法吗?

AND cast(convert(varchar(10), lag.postingdate, 112) as datetime) between '2015-01-01' and '2015-01-31' 

原始查询:

SELECT 
    prov.pgrp_id AS PERFORMING_PROV_ID 
    , prov.pgrp_prov_name AS PERFORMING_PROV_NAME 
    , lag.chgno AS CHARGE_NUM 
    , lag/countcharges AS LAGTIME 
    , lag.chgamt 
    , lag.postingdate 
FROM 
    dbo.Providers prov 
RIGHT JOIN 
    dbo.LagTime_Charges_Calcs lag ON prov.pgrp_prov_cd = lag.provcode 
            AND prov.pgrp_practice = lag.px 
LEFT JOIN 
    dbo.PlaceofService_union_v pos ON lag.px = pos.px 
            AND lag.poscode = pos.poscode 
WHERE 
    pos.posid = '1' 
    OR pos.posid = '2' 
    AND prov.Laginclude = 'y' 
    AND MONTH(lag.postingdate) = 1 
    AND YEAR(lag.postingdate) = 2015 

    --and lag.postingdate between '2015-01-01 00:00:00.000' and '2015-01-31 23:59:59.000' 
    --AND cast(convert(varchar(10),lag.postingdate,112) as datetime) between '2015-  01-01' and '2015-01-31' 
+1

你为什么要转换为字符串?试试'WHERE lag.postingdate> ='20150101'AND lag.postingdate <'20150201';'。请阅读[本文](http://sqlblog.com/blogs/aaron_bertrand/archive/2009/10/16/bad-habits-to-kick-mishandling-date-range-queries.aspx)和[本文] (http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx)。 – 2015-02-10 20:51:08

+0

另外,停止谈论“格式” - 什么是实际的*数据类型*?该视图是否呈现该输出,因为它出于某种原因将日期/时间值格式化为字符串?如果是这样,停止这样做... – 2015-02-10 20:58:01

+0

上面的例子不适合我。此列的数据类型是(datetime,null) – gfuller40 2015-02-10 21:02:25

回答

0

试试这个:

declare 
    @period_start datetime , 
    @period_end datetime 

set @period_start = '2015-01-01 00:00:00.000' 
set @period_end = dateadd(month,1,@period_start) 

select * 
from foo 
where foo.myDateTimeColumn >= @period_start 
    and foo.myDateTimeColumn < @period_end 
+0

消息139,级别15,状态1,行0 无法将默认值分配给本地变量。 消息139,级别15,状态1,行0 无法将默认值分配给本地变量。 Msg 137,Level 15,State 2,Line 16 必须声明标量变量“@periods_start” – gfuller40 2015-02-10 21:06:08

+0

@ gfuller40听起来像您正在使用SQL Server 2005,而不是SQL Server 2008,就像您的问题被标记了一样。 – 2015-02-10 21:08:40

+0

哦,废话你是对的(9.0.5000)我的坏..我从来没有在这台服务器上,我们所有的其他人都是2008年。 – gfuller40 2015-02-10 21:12:49

0

好方法(将使用postingdate列索引)

where lag.postingdate >= '20150101' 
and lag.postingdate < '20150201' 

容易,但低效的方式(不会使用任何索引,即使有在这个日期列)

where MONTH(lag.postingdate) = 1 
and YEAR(lag.postingdate) = 2015 
+0

感谢您的回复,但这两个例子似乎都不起作用,我仍然得到了2008年的所有日期。他们没有时间值,只是占位符:2008-01-24 00:00:00.000 – gfuller40 2015-02-10 20:54:52

+0

@ gfuller40发布您写下的查询。 – 2015-02-10 20:55:54

-1

为什么你不跳过所有的铸造?

和“2015年1月1日00:00:00”和“23:59:59 2015年1月31日”

注加时之间lag.postingdate做出的包容性条件开始和结束的日期 - 开始并不重要,但是结果在1月31日之前除了第一秒之外将会错过任何事情。

+0

您的查询仍然可能会遗漏数据。见http://sqlblog.com/blogs/aaron_bertrand/archive/2011/10/19/what-do-between-and-the-devil-have-in-common.aspx – 2015-02-10 20:58:38

+0

我也试过这个,仍然没有去..这是否与这是一个观点的事实有关? – gfuller40 2015-02-10 21:06:49

0

的真正原因你获得额外的结果要回到2008年了,因为查询的书面被包括posid =“1”不管帐日期的一切。

你需要将你的逻辑与的条件用括号:

WHERE (pos.posid='1' OR pos.posid ='2') and prov.Laginclude ='y' 
and MONTH(lag.postingdate) = 1 and YEAR(lag.postingdate) = 2015 

如果使用pos.posid IN ('1', '2')可以避开括号问题为好。