我有这张桌子:
create table #tbl
(
dt datetime
)
insert into #tbl values ('2013-01-01 00:00:00')
insert into #tbl values ('2013-02-01 00:00:00')
insert into #tbl values ('2013-02-02 00:00:00')
insert into #tbl values ('2013-03-01 00:00:00')
我需要得到每个不同月份的开始和结束,换句话说,这是预期的结果:
[start] [end]
2013-01-01 00:00:00.000 2013-01-31 23:59:59.997
2013-02-01 00:00:00.000 2013-02-28 23:59:59.997
2013-03-01 00:00:00.000 2013-03-31 23:59:59.997
我不知道该怎么做。 Plz帮助。
select
dateadd(mm, datediff(mm, 0, ???, 0),
dateadd(ms, -3, dateadd(mm, datediff(m, 0, ??? + 1, 0))
我正在使用MS SQL Server 2008。
答案 0 :(得分:1)
试试这个:
SELECT DISTINCT DATEADD(month, DATEDIFF(month, 0, MyDate), 0) as startOfMonth,
DATEADD(day, -1, DATEADD(month, 1, DATEADD(day, 1 - day(MyDate), MyDate))) as endOfMonth
FROM MyTable
答案 1 :(得分:1)
;with dm as (
select distinct rm = datediff(mm, 0, dt)
from #tbl t
)
select ms.[start], me.[end]
from dm
cross apply (select dateadd(mm, dm.rm, 0)) ms([start])
cross apply (select dateadd(ms, -3, dateadd(month, 1, ms.Value))) me([end])
逻辑如下。对于表格中的每个日期,查找自{date} rm
起的0
天数(即自1900年1月以来,cast(0 as datetime)
为1900年1月1日)。为避免重复使用distinct
:
select distinct rm = datediff(mm, 0, dt)
from #tbl t
上述语句包含在名为dm
的CTE中。然后,对于dm
中的每一行,使用表达式dateadd(mm, dm.rm, 0)
计算相应月份开始的日期(添加自1900年1月以来经过的月数,即使原始日期位于中间)。它被添加到使用cross apply
构造进行查询,因为它的值不仅会用于select
,还会用于计算月末日期。结束日期的计算方法是,将一个月添加到开始日期并减去3毫秒(以便结束日期不是下个月开始的日期)。
答案 2 :(得分:0)
对于结束日期,您可以在该月的第一天添加1个月,然后减去3毫秒。
SELECT
[end] = DATEADD(ms,-3, DATEADD(MM,1,DATEADD(MM,DATEDIFF(MM,0,dt),0)))