我想在两个日期之间选择数据,没有一天
输入示例:
开始月份:9,开始年份:2011年 结束月份:3,结束年份:2012年
我认为有两种方法可以做到这一点。
第一个是转换开始月份和开始年份到日期,如2011-09-01
并将最后一个日期转换为2012-03-31
,但这需要计算结束月份的最后一天。获得这些日期我们可以为WHERE子句使用BEETWEN函数(但是,CONVERT函数是可靠的吗?)
第二种解决方案是使用DATEPART
函数,如下面的代码所示:
我试着解释一下:如果结束年份等于初始年份,那么月份必须在开始和结束月份之间;否则,如果最后几个月大于初始年份,如果与初始年份和最后一年不同,我会把一切都介于两者之间;否则,如果最后一年,月份必须小于或等于最后一个月,如果初始年份,月份必须大于或等于最后一个月
你能帮助我以最好的方式做到这一点吗?是的,我采用的解决方案是什么?
declare @IndDebitoCredito bit,@ProgTributo int,@mi as integer,@ai as integer,@mf as integer,@af as integer,@IDAnagrafica varchar(5)
select @mi = 01,@ai = 2011,@mf = 12,@af = 2011,@IDAnagrafica = 'DELEL',@IndDebitoCredito = 1
select distinct rrd.IDTributo
from TBWH_Delega d
--inner join TBWH_SezioneDelega sd on d.IDDelega = sd.IDDelega
inner join TBWH_Rigo rd on rd.IDDelega = d.IDDelega
inner join TBWH_RataRigo rrd on rrd.IDRigo = rd.IDRigo
where
(
DATEPART(MM,d.DataDelega)<=@mf and
DATEPART(MM,d.DataDelega)>=@mi and
DATEPART(YYYY,d.DataDelega)=@ai and
@af = @ai
)
OR
(
--anno finale magg. anno iniziale
@af > @ai AND
(
( -- delega nell'intervallo
DATEPART(YYYY,d.DataDelega)<@af AND
DATEPART(YYYY,d.DataDelega)>@ai
-- DATEPART(MM,d.DataDelega)>=@mi
)
OR
( -- delega limite destro
DATEPART(YYYY,d.DataDelega)=@af AND
DATEPART(MM,d.DataDelega)<=@mf
)
OR
( -- delega limite sinistro
DATEPART(YYYY,d.DataDelega)=@ai AND
DATEPART(MM,d.DataDelega)>=@mi
)
)
)
GO
答案 0 :(得分:2)
你的第一个解决方案几乎就在那里,但是比它需要的更复杂,无论如何都不会起作用。它将错过结束月份最后一天的任何行。
您可以在end month
添加一个月,然后在每个月的第一天使用BETWEEN。例如
start month: 9 , start year: 2011
end month: 3, end year: 2012
BETWEEN '2011-09-01' AND '2012-04-01'
DataDelega >= '2011-09-01' AND DataDelega < '2012-04-01'
你需要添加一些逻辑来处理end month
12月,但这看起来是最简单的方法。
答案 1 :(得分:1)
你 WAY 过于复杂。你真的只需要两个比较:
尝试:
SELECT *
FROM MyTable
WHERE Datefield BETWEEN
CAST(@mi as varchar) + '/1/' + CAST(@ai as varchar)
-- first of first month
AND
DATEADD(DAY, -1, (DATEADD(Month, + 1, (CAST(@mf as varchar) + '/1/' + CAST(@af as varchar)))))
-- Last day or final month
答案 2 :(得分:0)
SELECT *
FROM Table
WHERE DateField
BETWEEN CONVERT(DATE, CONVERT(CHAR(4), @ai) + RIGHT('00' + CONVERT(VARCHAR(2), @mi), 2) + '01', 112)
AND DATEADD(DD, -1, DATEADD(MM, 1, CONVERT(DATE, CONVERT(CHAR(4), @af) + RIGHT('00' + CONVERT(VARCHAR(2), @mf), 2) + '01', 112)))
避免在DateField列上使用表达式,因为它使查询不是SARGable。
答案 3 :(得分:0)
我会用:
WHERE DateToCheck >= --- first day of StartMonth
DATEADD( mm, @StartMonth-1,
DATEADD( yy, @StartYear-2000, '2000-01-01')
)
AND DateToCheck < --- first day of next month (after EndMonth)
DATEADD( mm, @EndMonth,
DATEADD( yy, @EndYear-2000, '2000-01-01')
)
答案 4 :(得分:0)
DECLARE @mi INT
, @ai INT
, @mf INT
, @af INT
SELECT @mi = 01
, @ai = 2011
, @mf = 12
, @af = 2011
--local variables to hold dates
DECLARE @i DATETIME
, @f DATETIME
--build strings to represent dates in YYYYMMDD format
--add a month to the @f date
SELECT @i = CONVERT(VARCHAR(4), @ai) + RIGHT('0' + CONVERT(VARCHAR(2), @mi),
2) + '01'
, @f = DATEADD(month, 1,
CONVERT(VARCHAR(4), @af) + RIGHT('0'
+ CONVERT(VARCHAR(2), @mf),
2) + '01')
--select data where date >= @i, and < @f
SELECT *
FROM MyTable
WHERE DateField >= @i
AND DateField < @f