views:

245

answers:

3

I have this SQL now:

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

This works ok, but It is not taking into account months with 31 days and I am not getting back today's date for some reason.

+1  A: 

Try this (using AdventureWorks as sample database)

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

Will output

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

EDIT: Updated to include all interval dates

Rubens Farias
This doesn;t seem to be working correctly. The grouping isn't working for me and where am I supposed to use the @firstDayLastMonth? Thanks
DDiVita
I figured out why the grouping wasn't working. It had to do with the dates havine times included.
DDiVita
A: 

HEre is a modified version of Ruben's answer:

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)
DDiVita
A: 

OK, I got it. Rubens gave me an idea so I modified my SQL like so:

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)
DDiVita
why do you need `Substring(Convert(CHAR(10),Convert(CHAR(10),calendarday,101)),1,11)` ?
Rubens Farias
I do not want to show the time. It was grouping by date and time and not just by date.
DDiVita