我在SQL服务器中有一个看起来像这样的表(还有其他字段,但我只关心了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
我创建了这个查询:
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日添加到我的结果集中?我想过UNION
,但那些似乎与GROUP BY
的效果不佳。
在试图弄清楚并查看我的查询之后,我想我完全是在设计这个。对于这么简单的事情,我的查询看起来很复杂。有人可以帮我解决这个问题吗?
答案 0 :(得分:1)
试试这个:
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
这会将当天之前的天数视为属于当月,而其他人则是从上个月开始,然后总结。请告诉我这是否符合您的期望。
答案 1 :(得分:1)
我使用日历表(http://www.dbdelta.com/calendar-table-and-datetime-functions/),如下所示:
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