帮助SQL获得今天和之前一个月的每日点击次数

时间:2009-11-30 23:25:44

标签: sql-server datetime

我现在有这个SQL:

CREATE PROCEDURE dbo.sel_Track_HitsLast30Days(
@projectID int
)
AS
BEGIN
 DECLARE @FirstDay smalldatetime, @NumberOfMonths int, @priorMonth smalldatetime
set @priorMonth = (SELECT CAST(
(
STR( YEAR( dateadd(m,-1, getDate()) ) ) + '/' +
STR( MONTH( dateadd(m,-1, getDate()) ) ) + '/' +
STR( DAY( dateadd(m,-1, getDate()) ) )
)
AS DateTime 
))
Select @FirstDay = @priorMonth, @NumberOfMonths = 1
;WITH Days AS (
SELECT @FirstDay as CalendarDay
UNION ALL
SELECT DATEADD(d, 1, CalendarDay) as CalendarDay
FROM Days
WHERE DATEADD(d, 1, CalendarDay) < DATEADD(m, @NumberOfMonths, @FirstDay+1)
)
SELECT calendarday,foundDate.TotalbyDate,foundDate.date FROM Days

LEFT OUTER JOIN (

SELECT
COUNT(LEFT(visitDateTime, 11)) AS TotalbyDate,substring(convert( char(10), CONVERT( char(10), visitDateTime, 121 ) ), 1, 11) AS date

FROM
  dbo.TrackingData
WHERE
  visitDateTime >= dateadd(d, datediff(d, 0, getdate()), -30) and projectID = @projectID
  GROUP BY substring(convert( char(10), CONVERT( char(10), visitDateTime, 121 ) ), 1, 11)


) foundDate on foundDate.date = CalendarDay

order by 
CalendarDay Desc
END

这项工作正常,但是没有考虑到31天的月份,而且由于某种原因我没有回到今天的日期。

3 个答案:

答案 0 :(得分:1)

尝试此操作(使用AdventureWorks作为示例数据库)

DECLARE @today datetime, @NumberOfMonths int, @FirstDay smalldatetime
SELECT  @today = '2004-03-09', -- getdate(), tests only
        @NumberOfMonths = 1, 
        @FirstDay = CAST(FLOOR(CAST(
                         DATEADD(M, -1, @today) AS float)) AS datetime);
WITH Days AS
(
    SELECT @FirstDay AS  CalendarDay UNION ALL
    SELECT DATEADD(d, 1, CalendarDay) AS CalendarDay FROM Days
    WHERE  DATEADD(d, 1, CalendarDay) < DATEADD(m, @NumberOfMonths, @FirstDay+1)
)
SELECT   CONVERT(varchar(10), CalendarDay, 111) as [Date],
         COUNT(TransactionDate) as [Count] 
FROM     Days LEFT JOIN Production.TransactionHistory
ON       TransactionDate = Days.CalendarDay
GROUP BY CalendarDay
ORDER BY CalendarDay

将输出

Date       Count
---------- -----------
2004/02/09 272
2004/02/10 308
2004/02/11 264
2004/02/12 265
2004/02/13 250
...

编辑:已更新,以包含所有间隔日期

答案 1 :(得分:0)

HEre是Ruben答案的修改版本:

DECLARE  @today             DATETIME,
         @firstDayLastMonth DATETIME,
         @daysCount int

SET @today = getDate()
SET @firstDayLastMonth = Dateadd(m,-1,Dateadd(d,-Day(@today) + 1,@today))
Set @daysCount = (select datepart(dd,dateadd(dd,-1,dateadd(mm,1,cast(cast(year(@firstDayLastMonth) as varchar)+'-'+cast(month(@firstDayLastMonth) as varchar)+'-01' as datetime)))))

SELECT   substring(convert( char(10), CONVERT( char(10), visitDateTime, 121 ) ), 1, 11) AS [Date], Count(* ) AS [Count]
FROM     dbo.TrackingData
WHERE    visitdatetime >= Dateadd(d,-@daysCount,@today)
GROUP BY substring(convert( char(10), CONVERT( char(10), visitDateTime, 121 ) ), 1, 11)
ORDER BY substring(convert( char(10), CONVERT( char(10), visitDateTime, 121 ) ), 1, 11)

答案 2 :(得分:0)

好的,我明白了。鲁本斯给了我一个主意,所以我修改了我的SQL:

DECLARE  @FirstDay       SMALLDATETIME,
         @NumberOfMonths INT,
         @priorMonth     SMALLDATETIME,
         @firstDayLastMonth DateTime,
         @daysCount int
set @firstDayLastMonth = dateadd(m, -1,      dateadd(d, -day(getDate()) + 1, getDate()))
set @daysCount = (select datepart(dd,dateadd(dd,-1,dateadd(mm,1,cast(cast(year(@firstDayLastMonth) as varchar)+'-'+cast(month(@firstDayLastMonth) as varchar)+'-01' as datetime)))))
SET @priorMonth = (SELECT Cast((Str(Year(Dateadd(m,-1,Getdate()))) + '/' + Str(Month(Dateadd(m,-1,Getdate()))) + '/' + Str(Day(Dateadd(m,-1,Getdate())))) AS DATETIME))

Declare @before dateTime
Set @before = Dateadd(d,-@daysCount,getdate())
SELECT @FirstDay = @before,
       @NumberOfMonths = 1;

WITH days
     AS (SELECT @FirstDay AS calendarday
         UNION ALL
         SELECT Dateadd(d,1,calendarday) AS calendarday
         FROM   days
         WHERE  Dateadd(d,1,calendarday) <= Dateadd(m,@NumberOfMonths,@FirstDay))

 SELECT   Substring(Convert(CHAR(10),Convert(CHAR(10),calendarday,101)),
                                             1,11) ,
         founddate.totalbydate,
         founddate.DATE
FROM     days  
 LEFT OUTER JOIN (SELECT   Count(Left(visitdatetime,11)) AS totalbydate,
                                   Substring(Convert(CHAR(10),Convert(CHAR(10),visitdatetime,101)),
                                             1,11) AS DATE
                          FROM     dbo.trackingdata
                          WHERE    visitdatetime >= Dateadd(d,Datediff(d,0,Getdate()),-29)
                                   AND projectid = 131
                          GROUP BY Substring(Convert(CHAR(10),Convert(CHAR(10),visitdatetime,101)),
                                             1,11)) founddate
           ON founddate.DATE = Substring(Convert(CHAR(10),Convert(CHAR(10),calendarday,101)),
                                             1,11)