Here i'm Trying to create stored procedure.. group by detepart..is it correct or wrong.??
CREATE PROCEDURE sp_NewvsOldOrders
(
#StartDate DATETIME,
#EndDate DATETIME
)
AS BEGIN
DECLARE #NewCount INT
, #NewRevenue INT
, #NewDate DATETIME
SELECT
#NewDate = DATEPART(DAY, od.OrderDate)
, #NewCount = COUNT(*)
, #NewRevenue = SUM((CONVERT(DECIMAL(18, 2), od.TotalAmount)))
FROM orderdetails od
INNER JOIN customer c
ON od.customerid = c.customerid
WHERE (CONVERT(DATETIME, (CONVERT(VARCHAR(50), od.orderdate, 101))) BETWEEN #StartDate AND #EndDate)
AND ((CONVERT(DATETIME, (CONVERT(VARCHAR(50), od.orderdate, 101)))) = (CONVERT(DATETIME, (CONVERT(VARCHAR(50), c.registereddate, 101)))))
AND (od.TransactionId IS NOT NULL)
AND (od.TransactionId <> '')
GROUP BY DATEPART(DAY, od.OrderDate)
, od.OrderDate
END
Perhaps this is how your stored procedures should be. As you didn't explain your requirement, i can really tell what you are trying to achieve
CREATE PROCEDURE sp_NewvsOldOrders
(
#StartDate DATETIME,
#EndDate DATETIME
)
AS BEGIN
-- not used
--DECLARE #NewCount INT
-- , #NewRevenue INT
-- , #NewDate DATETIME
SELECT
NewDate = DATEPART(DAY, od.OrderDate)
, NewCount = COUNT(*)
, NewRevenue = SUM((CONVERT(DECIMAL(18, 2), od.TotalAmount)))
FROM orderdetails od
INNER JOIN customer c
ON od.customerid = c.customerid
WHERE (od.orderdate >= StartDate)
AND (od.orderdate < DATEADD(DAY, 1, #EndDate))
AND (CONVERT(VARCHAR(50), od.orderdate, 101)
= CONVERT(DATETIME, c.registereddate, 101))
AND (od.TransactionId IS NOT NULL)
AND (od.TransactionId <> '')
GROUP BY DATEPART(DAY, od.OrderDate)
--, od.OrderDate
END
Related
When I call this with these parameters(#MediaSellerID = 138, #StartDate = N'9/1/2020', #EndDate = N'10/7/2020') it returns data successfully.
But when I passed these parameters(#MediaSellerID = 213,#StartDate = '8/4/2020',#EndDate = N'11/25/2020')
this error occurs.
Msg 530, Level 16, State 1, Procedure GetAvailableDatesforCampaign, Line 81 [Batch Start Line 2]
The statement terminated. The maximum recursion 100 has been exhausted before statement completion.
If anyone has this solution (OPTION(MAXRECURSION 0)) then please also mention this statement place. thanks
ALTER Procedure [dbo].[GetAvailableDatesforCampaign]
-- exec GetAvailableDatesforCampaign 2,getdate(),getdate()
#MediaSellerID int,
#StartDate datetime,
#EndDate datetime
AS
BEGIN
SET FMTONLY OFF
Declare #Frequency as varchar(200)
Declare #Weeks as varchar(200)
Declare #Days as varchar(200)
Declare #CopyDeadlineDays as int
Declare #DayItem as varchar(20)
Declare #WeekItem as varchar(200)
Declare #DayNumber as int
Delete from tblCampaignDates
select
#Frequency=MediaFrequency,
#Weeks=BroadcastDays,
#Days=BroadcastDaysWeeks,
#CopyDeadlineDays=Copydeadline
from
tblMediaSeller where MediaSeller_ID=#MediaSellerID
CREATE TABLE
#TempAvailableDates
(
AvailableDate datetime default GetDate()
)
CREATE TABLE
#TempAllDates
(
AllDate datetime,
DayNames varchar(20),
Weeknumber int
)
IF(#Frequency='Bi-Weekly' or #Frequency='Weekly' or #Frequency='Monthly')
BEGIN
DECLARE MY_CURSOR2 CURSOR
LOCAL STATIC READ_ONLY FORWARD_ONLY
FOR
SELECT DISTINCT
Item
FROM
dbo.SplitString(#Days)
OPTION (MAXRECURSION 0)
OPEN MY_CURSOR2
FETCH NEXT FROM MY_CURSOR2 INTO #DayItem
WHILE ##FETCH_STATUS = 0
BEGIN
-- Select All dates of those days in tblMediaSeller (Adv Publishing day) from start date to End dates
Set #DayNumber= CASE WHEN #DayItem='Monday' THEN 1
WHEN #DayItem='Tuesday' THEN 2
WHEN #DayItem='Wednesday' THEN 3
WHEN #DayItem='Thursday' THEN 4
WHEN #DayItem='Friday' THEN 5
WHEN #DayItem='Saturday' THEN 6
WHEN #DayItem='Sunday' THEN 7
ELSE 0 END
IF(#DayNumber<>0)
BEGIN
SET DATEFIRST #DayNumber; -- First day of the week is set to monday
WITH CTE(dt)
AS
(
SELECT #StartDate
UNION ALL
SELECT DATEADD(d, 1, dt)
FROM CTE
WHERE dt <#EndDate
)
INSERT INTO
#TempAllDates
SELECT
CONVERT(date,dt),
datename(dw, dt),
DATEDIFF(WEEK, DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0), dt)
FROM
CTE
WHERE
datepart ("dw", dt) = 1;
END
FETCH NEXT FROM MY_CURSOR2 INTO #DayItem
END
CLOSE MY_CURSOR2
DEALLOCATE MY_CURSOR2
Set #WeekItem= REPLACE(#Weeks, 'Week', '');
DECLARE #ActualStartDate as Datetime
Set #ActualStartDate = (Select top 1 AllDate from #TempAllDates)
IF(#CopyDeadlineDays is null)
BEGIN
IF(#ActualStartDate>= DATEADD(day,5,getdate()))
BEGIN
Insert into
#TempAvailableDates
Select
AllDate
From
#TempAllDates
WHERE
Weeknumber in (select cast(item as int) from dbo.SplitString(#WeekItem))
END
ELSE
BEGIN
Insert into
#TempAvailableDates
Select
AllDate
From
#TempAllDates
WHERE
Weeknumber in (select cast(item as int) from dbo.SplitString(#WeekItem))
AND AllDate>=DATEADD(day,5,getdate())
END
END
ELSE
BEGIN
IF(#ActualStartDate>= DATEADD(day,#CopyDeadlineDays,getdate()))
BEGIN
Insert into
#TempAvailableDates
Select
AllDate
From
#TempAllDates
WHERE
Weeknumber in (select cast(item as int) from dbo.SplitString(#WeekItem))
END
ELSE
BEGIN
Insert into
#TempAvailableDates
Select
AllDate
From
#TempAllDates
WHERE
Weeknumber in (select cast(item as int) from dbo.SplitString(#WeekItem))
AND AllDate>=DATEADD(day,#CopyDeadlineDays,getdate())
END
END
END
ELSE
BEGIN
IF(#CopyDeadlineDays is null)
begin
IF(#StartDate>= DATEADD(day,5,getdate()))
BEGIN
Insert into
#TempAvailableDates
SELECT TOP
(DATEDIFF(DAY, #StartDate, #EndDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #StartDate)
FROM
sys.all_objects a
CROSS JOIN
sys.all_objects b;
END
ELSE
BEGIN
SET #StartDate=#StartDate+5
Insert into
#TempAvailableDates
SELECT TOP
(DATEDIFF(DAY, #StartDate, #EndDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #StartDate)
FROM
sys.all_objects a
CROSS JOIN
sys.all_objects b;
END
END
ELSE
BEGIN
IF(#StartDate>= DATEADD(day,#CopyDeadlineDays,getdate()))
BEGIN
Insert into
#TempAvailableDates
SELECT TOP
(DATEDIFF(DAY, #StartDate, #EndDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #StartDate)
FROM
sys.all_objects a
CROSS JOIN
sys.all_objects b;
END
ELSE
BEGIN
SET #StartDate=#StartDate+#CopyDeadlineDays
Insert into
#TempAvailableDates
SELECT TOP
(DATEDIFF(DAY, #StartDate, #EndDate) + 1)
Date = DATEADD(DAY, ROW_NUMBER() OVER(ORDER BY a.object_id) - 1, #StartDate)
FROM
sys.all_objects a
CROSS JOIN
sys.all_objects b;
END
END
END
Insert into
tblCampaignDates
Select
AvailableDate
from #TempAvailableDates
Select AvailableDate from tblCampaignDates
END
This should work:
WITH CTE(dt) AS (
SELECT #StartDate
UNION ALL
SELECT DATEADD(d, 1, dt)
FROM CTE
WHERE dt <#EndDate
)
INSERT INTO #TempAllDates
SELECT CONVERT(date,dt), datename(dw, dt), DATEDIFF(WEEK, DATEADD(MONTH, DATEDIFF(MONTH, 0, dt), 0), dt)
FROM CTE
WHERE datepart(dw, dt) = 1
OPTION (MAXRECURSION 0);
Here is a db<>fiddle with a much simpler example.
I have this query developed with the help of a guy here and I am not able to use this in function.
There is some sort of Syntax issue.
Here is the query
WITH CTE AS (
SELECT #STARTDATE AS STARTDATE
UNION ALL
SELECT DATEADD(D,1,STARTDATE)
FROM CTE
WHERE STARTDATE <#ENDDATE
),
WORKINGDAYS AS (
SELECT STARTDATE,
DATENAME(DW,STARTDATE)WEEKDAYS,
C1.CalanderDayName AS isweekend
FROM CTE c
LEFT JOIN HRM.tbl_Calendar C1 ON DATENAME(DW,STARTDATE) = C1.CalanderDayName
AND C1.IsOffDay = 1
)
SELECT COUNT(WEEKDAYS)as WORKINGDAYS
FROM WORKINGDAYS
WHERE isweekend IS NULL;
I want to create a function named fnGetWorkingDays
ALTER FUNCTION [dbo].[fnGetWorkingDays] (#StartDate datetime, #EndDate datetime)
RETURNS int
AS
BEGIN
DECLARE #dateFrom datetime
DECLARE #dateTo datetime
SET #dateFrom = #StartDate
SET #dateTo = #EndDate
DECLARE #WORKDAYS INT
SELECT #WORKDAYS =
;WITH CTE AS (
SELECT #STARTDATE AS STARTDATE
UNION ALL
select DATEADD(D,1,STARTDATE)
FROM CTE
WHERE STARTDATE <#ENDDATE
)
,WORKINGDAYS AS (
SELECT STARTDATE,DATENAME(DW,STARTDATE)WEEKDAYS, C1.CalanderDayName AS isweekend
FROM CTE c
LEFT JOIN HRM.tbl_Calendar C1 ON DATENAME(DW,STARTDATE)=C1.CalanderDayName AND C1.IsOffDay=1
)
SELECT COUNT(WEEKDAYS)as WORKINGDAYS FROM WORKINGDAYS WHERE isweekend is null
RETURN #WORKDAYS
END
Try With this Below function .let me know back for any errors
CREATE FUNCTION [dbo].[fnGetWorkingDays] (#StartDate datetime, #EndDate datetime)
RETURNS int
AS
BEGIN
DECLARE #WORKDAYS INT
;WITH CTE AS (
SELECT #STARTDATE AS STARTDATE
UNION ALL
SELECT DATEADD(D,1,STARTDATE)
FROM CTE
WHERE STARTDATE <#ENDDATE
),
WORKINGDAYS AS (
SELECT STARTDATE,
DATENAME(DW,STARTDATE)WEEKDAYS,
C1.CalanderDayName AS isweekend
FROM CTE c
LEFT JOIN HRM.tbl_Calendar C1 ON DATENAME(DW,STARTDATE) = C1.CalanderDayName
AND C1.IsOffDay = 1
)
SELECT #WORKDAYS=COUNT(WEEKDAYS) FROM WORKINGDAYS WHERE isweekend is null
RETURN #WORKDAYS
END
You are getting the Error because your Assignment operation for the Variable #WORKDAYS is Wrong. Change it Like This
ALTER FUNCTION [dbo].[fnGetWorkingDays]
(
#StartDate DATETIME,
#EndDate DATETIME
)
RETURNS INT
AS
BEGIN
DECLARE #dateFrom DATETIME;
DECLARE #dateTo DATETIME;
SET #dateFrom = #StartDate;
SET #dateTo = #EndDate;
DECLARE #WORKDAYS INT;
WITH CTE
AS
(
SELECT
#STARTDATE AS STARTDATE
UNION ALL
SELECT
DATEADD(D, 1, STARTDATE)
FROM CTE
WHERE STARTDATE < #ENDDATE
),WORKINGDAYS
AS
(
SELECT
DATENAME(DW, STARTDATE) WEEKDAYS,
C1.CalanderDayName AS isweekend
FROM CTE c
LEFT JOIN HRM.tbl_Calendar C1
ON DATENAME(DW, STARTDATE) = C1.CalanderDayName
AND C1.IsOffDay = 1
)
SELECT
#WORKDAYS = COUNT(WEEKDAYS)--Asign Variable Here
FROM WORKINGDAYS
WHERE isweekend IS NULL;
RETURN #WORKDAYS;
END;
You have written wrong syntax to set #WORKDAYS, try below syntax
CREATE FUNCTION [dbo].[fnGetWorkingDays] (#StartDate datetime, #EndDate datetime)
RETURNS int
AS
BEGIN
DECLARE #WORKDAYS INT
;WITH CTE AS (
SELECT #STARTDATE AS STARTDATE
UNION ALL
select DATEADD(D,1,STARTDATE)
FROM CTE
WHERE STARTDATE <#ENDDATE
)
,WORKINGDAYS AS (
SELECT STARTDATE,DATENAME(DW,STARTDATE)WEEKDAYS, C1.CalanderDayName AS isweekend
FROM CTE c
LEFT JOIN HRM.tbl_Calendar C1 ON DATENAME(DW,STARTDATE)=C1.CalanderDayName AND C1.IsOffDay=1
)
SELECT #WORKDAYS=COUNT(WEEKDAYS) FROM WORKINGDAYS WHERE isweekend is null
RETURN #WORKDAYS
END
I'm trying to write a function to return the number of working days between 2 dates. I have a table with all the bank holidays in which has two fields: BHID and BHDate.
I've written the following SELECT query to test out my theory and it works nicely:
DECLARE #StartDate AS Date, #EndDate AS Date
SET #StartDate = '2015-01-01'
SET #EndDate = '2015-07-01'
;WITH CTE AS (
SELECT #StartDate AS StartDate, #EndDate AS EndDate, #StartDate AS DateCalc
UNION ALL
SELECT #StartDate AS StartDate, #EndDate AS EndDate, DATEADD(dd, 1, DateCalc) AS DateCalc FROM CTE
WHERE DATEADD(dd, 1, DateCalc) <= EndDate)
SELECT COUNT(*) AS Days
FROM CTE
LEFT JOIN psd.dbo.LUBankHolidays BH
ON CTE.DateCalc = BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, DateCalc) ,1) <> 'S'
option (Maxrecursion 0);
But when I try and put it in a function I get some errors around the SET line, it could be me just not being quite as good on functions as the rest of my knowledge or I was wondering whether it was to do with the CTE not having been used ahead of the SET line? Here's my attempt:
CREATE FUNCTION [dbo].[WorkingDays]
(#StartDate AS Date, #EndDate AS Date
)
RETURNS INT
AS
BEGIN
DECLARE #Days AS INT
;WITH CTE AS (
SELECT #StartDate AS StartDate, #EndDate AS EndDate, #StartDate AS DateCalc
UNION ALL
SELECT #StartDate AS StartDate, #EndDate AS EndDate, DATEADD(dd, 1, DateCalc) AS DateCalc FROM CTE
WHERE DATEADD(dd, 1, DateCalc) <= EndDate)
SET #Days =
(SELECT COUNT(*) AS Days
FROM CTE
LEFT JOIN psd.dbo.LUBankHolidays BH
ON CTE.DateCalc = BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, DateCalc) ,1) <> 'S'
option (Maxrecursion 0);)
RETURN #Days
END
I even tried inserting the result of the INT into a temporary table and then dropping this after setting #Days before then returning #Days but this then results in an error regarding not being allowed to produce temporary tables as part of a function.
Any help would be great, I'm sure it's a small thing but just escaping me currently.
Because a CTE can only be used in a query, rather than using SET to set the variable, use SELECT instead:
SELECT #Days =
(SELECT COUNT(*) AS Days
FROM CTE …
From MSDN:
A CTE must be followed by a single SELECT, INSERT, UPDATE, or DELETE
statement that references some or all the CTE columns.
Worked it out with stuartd's help:
CREATE FUNCTION [dbo].[WorkingDays]
(#StartDate AS Date, #EndDate AS Date
)
RETURNS INT
AS
BEGIN
DECLARE #Days AS INT
;WITH CTE AS (
SELECT #StartDate AS StartDate, #EndDate AS EndDate, #StartDate AS DateCalc
UNION ALL
SELECT #StartDate AS StartDate, #EndDate AS EndDate, DATEADD(dd, 1, DateCalc) AS DateCalc FROM CTE
WHERE DATEADD(dd, 1, DateCalc) <= EndDate)
SELECT #Days =
(SELECT COUNT(*) AS Days
FROM CTE
LEFT JOIN psd.dbo.LUBankHolidays BH
ON CTE.DateCalc = BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, DateCalc) ,1) <> 'S')
option (Maxrecursion 0);
RETURN #Days
END
Thanks All
Use this function
CREATE FUNCTION [dbo].[WorkingDays]
(#Start_Date AS Date, #end_Date AS Date
)
RETURNS INT
AS
BEGIN
DECLARE #Days AS INT
WITH AllDays
AS ( SELECT #start_date AS [Date], 1 AS [level]
UNION ALL
SELECT DATEADD(DAY, 1, [Date]), [level] + 1
FROM AllDays
WHERE [Date] < #end_date )
SELECT #Days =COUNT(*) AS Days
FROM AllDays
LEFT JOIN psd.dbo.LUBankHolidays BH
ON AllDays.Date= BH.BHDate
WHERE BHID IS NULL
AND LEFT(DATENAME(dw, AllDays.Date) ,1) <> 'S'
RETURN #Days
END
Referring back to this SO post
If there is a Grouping category "Category" which, for simplicity's sake, can be either X or Y - is it a trivial matter amending this script so that it will add in the missing dates for each of the categories ?
I assume the category will need adding into the CTE?
In other words if I have the following initial table:
...how do I get to the following:
Will upload my attempt shortly
I've called the initial table #x. I'm hoping to adapt a recursive CTE query like the following to include the field Category:
DECLARE #MinDate DATETIME;
SET #MinDate = (SELECT Min(DATE) FROM #x)
DECLARE #MaxDate DATETIME;
SET #MaxDate = (SELECT Max(DATE) FROM #x)
;WITH times AS
(
SELECT #MinDate dt , 1 depth
UNION ALL
SELECT
DATEADD(d, depth, #MinDate) dt
, 1 + depth as depth
FROM times
WHERE DATEADD(d, depth, #MinDate) <= #MaxDate
)
SELECT
*
FROM
TIMES t
LEFT OUTER JOIN #X x
ON
t.dt = x.Date
Ok - I've tied including a CROSS JOIN but it expands things incorrectly:
SELECT DISTINCT Category INTO #Cat FROM #x
DECLARE #MinDate DATETIME;
SET #MinDate = (SELECT Min(DATE) FROM #x)
DECLARE #MaxDate DATETIME;
SET #MaxDate = (SELECT Max(DATE) FROM #x)
;WITH times AS
(
SELECT
Category
, #MinDate dt
, 1 depth
FROM #Cat
UNION ALL
SELECT
c.Category
, DATEADD(d, depth, #MinDate) dt
, 1 + depth as depth
FROM
times t
CROSS JOIN #Cat c
--ON c.Category IS NOT NULL
WHERE DATEADD(d, depth, #MinDate) <= #MaxDate
)
SELECT
*
FROM
TIMES
This seems to have worked ok:
SELECT DISTINCT Category INTO #Cat FROM #x
DECLARE #MinDate DATETIME;
SET #MinDate = (SELECT Min(DATE) FROM #x)
DECLARE #MaxDate DATETIME;
SET #MaxDate = (SELECT Max(DATE) FROM #x)
;WITH times AS
(
SELECT
Category
, #MinDate dt
, 1 depth
FROM #Cat
UNION ALL
SELECT
Category
, DATEADD(d, depth, #MinDate) dt
, 1 + depth as depth
FROM
times t
WHERE DATEADD(d, depth, #MinDate) <= #MaxDate
)
SELECT
*
FROM
TIMES
Here is a solution without a calendar table (which is a must in production). You might have date range in variables, or you might go for min() and max() from the_table.
EDIT: shorter version incorporating categories into date range generation
declare #startdate datetime = '2012-1-1'
declare #enddate datetime = '2012-1-5'
; with dates([date], category) as (
select distinct #startdate, category
from the_table
union all
select dateadd (day, 1, [date]), category
from dates
where [date] < #enddate
)
select dates.date,
dates.category,
isnull(the_table.amount, 0) Amount
from dates
left join the_table
on dates.date = the_table.date
and dates.category = the_table.category
order by dates.category, dates.date
option (maxrecursion 0)
There is live test # Sql Fiddle.
New Sql Fiddle.
Something like this should do the trick:
declare #curDate datetime, #maxDate datetime
declare #count tinyint
select #curDate = convert(datetime, '20120101', 112), #maxDate = getdate()
select #count = 0
while #curDate < #maxDate
begin
select #count = count(1) from tablename where Category = 'X' and convert(varchar(8), Date, 112) = convert(varchar(8), #curDate, 112)
if #count > 0
begin
insert into tablename
select 'X', #curDate, 0
end
select #curDate = dateadd(dd, 1, #curDate)
end
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.
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
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)
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)