基于动态日期在SQL Server中提取一个月的行
我在SQL server中有一个表,看起来像这样还有其他字段,但我只关心以下两个字段:基于动态日期在SQL Server中提取一个月的行,sql,sql-server,sql-server-2008,tsql,Sql,Sql Server,Sql Server 2008,Tsql,我在SQL server中有一个表,看起来像这样还有其他字段,但我只关心以下两个字段: ----------------------------------------- | DraftDay (int)| MonthlyFee (money)| ----------------------------------------- 1 18.75 2 15.25 2
-----------------------------------------
| DraftDay (int)| MonthlyFee (money)|
-----------------------------------------
1 18.75
2 15.25
2 15.25
3 15.25
3 28.12
4 15.25
4 3.75
4 18.19
5 12.75
6 13.80
6 14.25
... ...
... ...
我试图做的是编写一个查询,该查询将按DraftDay分组,并对MonthlyFee字段求和。很简单。但最困难的是,我需要得到一个月前的日期,再加上一天,从那天到今天的天数。例如,如果今天是2014年4月3日,那么我需要提取2014年3月4日到2014年4月3日之间的所有天数。我的结果集应该如下所示:
3/4/2014 37.19
3/5/2014 12.75
3/6/2014 28.05
... ...
... ...
4/1/2014 18.75
4/2/2014 30.50
4/3/2014 43.37
declare @d datetime ='20140403'
select c.CalendarDate, sum(#t.MonthlyFee)
from calendar c
left join #t on c.CalendarDay = #t.DraftDay
where CalendarDate between dateadd(month, -1, @d)+1 and @d
group by c.CalendarDate
我已创建此查询:
SELECT
CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(CASE WHEN EftDraftDay>28 THEN 28 ELSE EftDraftDay END AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME) AS DraftDate,
SUM(MonthlyPayment) AS MonthlyPayment FROM dbo.Advertiser
WHERE IsDeleted=0
AND IsPaidInFull=0
AND IsAdvertiserActive=1
AND EftDraftDay>0
AND (CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(CASE WHEN EftDraftDay>28 THEN 28 ELSE EftDraftDay END AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME)) >=
CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(DATEPART(DAY, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME)
GROUP BY
CAST(CAST(DATEPART(MONTH, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(2)) + '/' +
CAST(CASE WHEN EftDraftDay>28 THEN 28 ELSE EftDraftDay END AS VARCHAR(2)) + '/' +
CAST(DATEPART(YEAR, DATEADD(DAY, 1, DATEADD(MONTH, -1, GETDATE()))) AS VARCHAR(4)) AS DATETIME)
因为今天的日期是2014年4月17日,所以我应该从2014年3月18日到2014年4月17日返回结果。我得到的结果只是从2014年3月18日到2014年3月28日。如何将2014年4月1日至2014年4月17日添加到我的结果集中?我曾考虑过成立工会,但这些工会似乎与GROUP BY的工会不太合拍
在试图弄明白这一点并查看我的查询后,我认为我完全超出了设计范围。对于如此简单的事情,我的查询看起来如此复杂。有人能帮我解决这个问题吗?试试这个:
declare @lastmonth date = convert(date,dateadd(day,1,dateadd(month,-1,getdate())))
declare @thismonth date = convert(date,getdate())
select
case
when draftday < datepart(day,@thismonth)
then convert(date, cast(datepart(yyyy,@thismonth) as varchar) + right('00'+cast(datepart(MM,@thismonth) as varchar),2) + right('00'+cast(cast(draftday as varchar) as varchar),2))
else convert(date, cast(datepart(yyyy,@lastmonth) as varchar) + right('00'+cast(datepart(MM,@lastmonth) as varchar),2) + right('00'+cast(cast(draftday as varchar) as varchar),2))
end,
sum(monthlyfee) from tbl
group by draftday
这将把当前日期之前的天数视为属于当前月份,其他天数则视为属于上个月,然后进行汇总。请让我知道这是否符合您的期望。我会使用日历表,类似这样:
3/4/2014 37.19
3/5/2014 12.75
3/6/2014 28.05
... ...
... ...
4/1/2014 18.75
4/2/2014 30.50
4/3/2014 43.37
declare @d datetime ='20140403'
select c.CalendarDate, sum(#t.MonthlyFee)
from calendar c
left join #t on c.CalendarDay = #t.DraftDay
where CalendarDate between dateadd(month, -1, @d)+1 and @d
group by c.CalendarDate
DraftDay列和实际日期之间的关系是什么?@dean-DraftDay只是monthAnd的一部分,你怎么知道它代表的是三月还是四月?@dean-我使用的是GetDate这段代码有效,它肯定比我原来的查询简单得多。除了我不得不把它改为当draftday日历表可能是不必要的,但这是一个小问题。更严重的是,您使用+1添加一天。这只适用于datetime和smalldatetime值,如果OP将日期存储在日期列中,则不起作用。DATEADDDAY。。。将是唯一的方法。在+1问题上几乎正确,但getdate在2008年仍然返回datetime:。OTOH,日历表是一个必须的数字表啊,事实上,您只是将它应用于变量,您恰当地将其声明为datetime。对不起,我应该在周五晚上评论的时候更加谨慎。我非常重视你的评论,谢谢。哦,这真的很好,也让人放心,谢谢你。