Incorrect syntax near my alias when joining sub-queries? - sql

My code is provided below. I get the error
"Incorrect syntax near the keyword 'otb'" (line 48)
and
"Incorrect syntax near the keyword 'otb_ly' "
I have no idea what this could mean! Because it makes sense to me to join my two sub-queries (that I've named otb and otb_ly).
On their own the sub-queries work just fine.
declare #snapLY table (hotel_id tinyint, import_date date)
insert into #snapLY select hotel_id, max(import_date) from [UKRMC].[dbo].[block_res]
where import_date <= convert(date, DATEADD(day, 1, DATEADD(year, -1, GETDATE()) ) )
group by hotel_id
select otb.sita,
otb.month_TY,
otb.year_TY,
otb.Market_segment,
otb.rn_TY as OTB_rn_TY,
otb.rev_TY as OTB_rev_TY
--otb_ly.rev_LY as OTB_rev_LY,
--otb_ly.rn_LY as OTB_rn_LY
(
select contacts.sita,
data.hotel_id,
data.month_TY
,data.year_TY
,Market_segment = seg.SEG
,rn_TY = ISNULL(datatwo.rn_TY,0)
,rev_TY = ISNULL(datatwo.rev_TY, 0)
from (
SELECT hotel_id, datename(month, DATEARRIVED) as month_TY, datename(year, DATEARRIVED) year_TY
FROM [UKRMC].[dbo].[revenue] rev
JOIN [UKRMC].[dbo].[contacts] contacts on rev.hotel_id = contacts.ID
WHERE DATEARRIVED BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101') -- first day of the month
AND DATEADD(MONTH, 5, DATEADD(DAY,-DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE()))) -- 6 months later
and sita not like '%GLARR%'
group by hotel_id, datename(month, DATEARRIVED), datename(year, DATEARRIVED)
) data
cross join (
select SEG
from [UKRMC].[dbo].[Segmentation]
where SEG in ('RAC', 'BIT', 'BIQ', 'CBI', 'TOF', 'QOF', 'BAO', 'FIT', 'LYO', 'RER', 'OTH', 'NRG', 'XXX', 'CRW', 'BGR', 'BGO', 'LGR', 'LGS')
) seg
left join (
SELECT hotel_id, market_segment, datename(month, DATEARRIVED) month_TY, datename(year, DATEARRIVED) year_TY, sum(AMTROOM) as rev_TY, sum(STAYDAYS) as rn_TY
FROM [UKRMC].[dbo].[revenue] revtwo
WHERE DATEARRIVED BETWEEN DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101') -- first day of the month
AND DATEADD(MONTH, 5, DATEADD(DAY,-DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE()))) -- 6 months later
AND hotel_id != 61 --not GLARR, id taken from contacts table
GROUP BY hotel_id, datename(month, DATEARRIVED), datename(year, DATEARRIVED), market_segment
) datatwo on data.hotel_id = datatwo.hotel_id and seg.SEG = datatwo.market_segment and data.month_TY = datatwo.month_TY and data.year_TY = datatwo.year_TY
join [UKRMC].[dbo].[contacts] contacts on contacts.id = data.hotel_id
) otb
LEFT JOIN
(
SELECT sita, market_seg, month_LY, year_LY, sum(rev_LY) as rev_LY, sum(rn_LY) as rn_LY
FROM (
SELECT block.hotel_id, SITA
,datename(month,stay_date) as month_LY
,datename(year, stay_date) as year_LY
,sum(rev_room) as rev_LY
,sum(quantity) as rn_LY
,market_seg
FROM [UKRMC].[dbo].[block_res] block
JOIN #snapLY spit on block.hotel_id = spit.hotel_id and block.import_date = spit.import_date
JOIN [UKRMC].[dbo].[Contacts] contacts on block.hotel_id = contacts.ID
WHERE stay_date >= DATEADD(year, -1, DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101'))
--stay_date >= DATEADD(year, -1, getdate())
and stay_date <= DATEADD(year, -1, DATEADD(MONTH, 5, DATEADD(DAY,-DAY(DATEADD(MONTH, 1, GETDATE())), DATEADD(MONTH, 1, GETDATE()))))
group by sita, market_seg, block.hotel_id, datename(month,stay_date),datename(year, stay_date)
UNION ALL
SELECT revenue.HOTEL_ID, SITA
,datename(month,DATEARRIVED) as month_LY
,datename(year,DATEARRIVED) as year_LY
,sum(AMTROOM) as rev_LY
,sum(STAYDAYS) as rn_LY
,market_segment
FROM [UKRMC].[dbo].[revenue] revenue
JOIN [UKRMC].[dbo].[Contacts] contacts on revenue.HOTEL_ID = contacts.ID
JOIN #snapLY spit on revenue.HOTEL_ID = spit.hotel_id
WHERE DATEARRIVED between DATEADD(year, -1, DATEADD(MONTH, DATEDIFF(MONTH, '19000101', GETDATE()), '19000101'))
and DATEADD(day, -1, DATEADD(year, -1, getdate()))
and DATEARRIVED < spit.import_date
GROUP BY sita, revenue.HOTEL_ID, datename(month,DATEARRIVED), datename(year,DATEARRIVED), market_segment
) union_LY
GROUP BY sita, market_seg, hotel_id, month_LY, year_LY
) otb_ly
on otb.sita = otb_ly.sita and otb.Market_segment = otb_ly.market_seg and otb.month_LY = otb_ly.month_LY and otb.year_LY = otb_ly.year_LY

You're missing a FROM on Line 14:
...
--otb_ly.rn_LY as OTB_rn_LY
FROM
(
...
That query, in all honestly, needs a massive rework... That is really difficult to read.

Related

How to get value 0 if the result of sql select except statement return no records?

I have a problem with the SQL Except statement, in my case, I select two columns and one column can have values and the others cannot have because the count of the first SQL statement equals the count of the second SQL after the except statement.
Result that I got :
GroupId absences
1 3
Expected result
GroupId absences
1 3
2 0
How can I do in this case?
select
groupId,
(case when groupId = null then 0 else COUNT(*) end) as absence
from (
select
groupId,
COUNT(*) as absences1
from (
select distinct
MONTh,
DAY,
e.groupId
from employee_c c,
holiday hl,
employee e,
groups,
Get_Calendar_Date(
DATEADD(MONTH, DATEDIFF(MONTH, 0, CAST(DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) AS datetime)) + #Month - 1, 0),
DATEADD(MONTH, DATEDIFF(MONTH, -1, CAST(DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) AS datetime)) + #Month-1, -1)
)
where DATENAME(DD, Weekday) IN (
select WorkingdayId+1
from timetable s,
groups ds,
grouptime de
where dd.groupId = ds.groupId
and dd.groupId = de.groupId
and s.timetableId = de.timetableId
and de.groupId = ds.groupdId)
and DATEPART(MM,hl.startDate) = #Month
and c.isActive=1
except
(select Month,
Day,
d.departmentId
from department d,
Get_Calendar_Date(
DATEADD(MONTH, DATEDIFF(MONTH, 0, CAST(DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) AS datetime)) + #Month - 1, 0),
DATEADD(MONTH, DATEDIFF(MONTH, -1, CAST(DATEADD(yy, DATEDIFF(yy, 0, GETDATE()), 0) AS datetime)) + #Month - 1, -1)
),
holiday hle,
employee_c c,
employee e
where datepart(MM,hle.startDate) = #Month
and cast(Date as date) between hle.startDate and hle.endDate
and c.isActive=1
and d.groupId =e.groupId
and c.employeeId=e.employeeId
and c.isActive=1
)
) sc
group by Month,Day,groupId
) s
group by groupId

Issue with TSQL Query only returns months that have values and not 0 as needed

The following TSQL returns last 6 month count of data, but if a month does not have records it does not just return 0 as I need it to do, how can I make it do so?
declare #thismonth as Date = DateAdd(d, 1 - DatePart(d, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
declare #firstmonth as Date = DateAdd(m, -6, #thismonth);
SELECT YEAR(StartDate) year,
MONTH(StartDate) month,
COUNT(StartDate) EmployeeStartet
FROM
EFP_EmploymentUser
WHERE StartDate BETWEEN #firstmonth AND #thismonth
GROUP BY YEAR(StartDate), MONTH(StartDate)
ORDER BY YEAR(StartDate) DESC, MONTH(StartDate) DESC;
You could do something like this:
declare #lastMonth as Date = DateAdd(d, 1 - DatePart(d, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
declare #firstMonth as Date = DateAdd(m, -6, #lastMonth);
WITH months AS (
SELECT #firstMonth AS thisMonth
UNION ALL
SELECT DateAdd(m, 1, thisMonth) AS thisMonth
FROM months
WHERE thisMonth < #lastMonth
),
data AS (
-- your sql here
SELECT YEAR(StartDate) year,
MONTH(StartDate) month,
COUNT(StartDate) EmployeeStartet
FROM
EFP_EmploymentUser
WHERE StartDate BETWEEN #firstmonth AND #thismonth
GROUP BY YEAR(StartDate), MONTH(StartDate)
)
SELECT
YEAR(m.thisMonth) AS year,
MONTH(m.thisMonth) AS month,
ISNULL(d.EmployeeStartet, 0) AS EmployeeStartet
FROM months m
LEFT OUTER JOIN data d
ON
d.year = YEAR(m.thisMonth)
AND d.month = MONTH(m.thisMonth)
ORDER BY m.thisMonth DESC
Left join your data to a tally
declare #thismonth as Date = DateAdd(d, 1 - DatePart(d, CURRENT_TIMESTAMP), CURRENT_TIMESTAMP);
declare #firstmonth as Date = DateAdd(m, -6, #thismonth);
with m as (
select #firstMonth md union
select DateAdd(m, 1, #firstMonth) union
select DateAdd(m, 2, #firstMonth) union
select DateAdd(m, 3, #firstMonth) union
select DateAdd(m, 4, #firstMonth) union
select DateAdd(m, 5, #firstMonth)
),
ym as (
select YEAR(md) y, MONTH(md) m
from m
)
select ym.y, ym.m, COUNT(e.StartDate) EmployeeStartet
from ym
left join EFP_EmploymentUser e
ON (e.StartDate BETWEEN #firstmonth AND #thismonth)
AND ym.y = YEAR(e.StartDate) AND ym.m = MONTH(e.StartDate)
GROUP BY ym.y, ym.m
ORDER BY ym.y DESC, ym.m DESC;

SQL Server grouped rows return with default values if no row available for a date period

I'm trying to write a stored procedure which groups up rows based on their month and return a sum of all items if they exist and 0 if they don't.
For the date part of the query, what I am trying to get is today's date - extract the month and go back 5 months to gather any data if it exists.
At this stage, the query runs fine as is but I'm wondering if there's any way to optimise this as it looks like I'm running the same set of data over and over again and also it's hard coded to an extent.
The dataset I am trying to achieve is as follows:
Month TotalAmount TotalCount
-----------------------------------
2017-11 0 0
2017-12 200.00 2
2018-01 300.00 3
2018-02 0 0
2018-03 300.00 3
2018-04 100.00 1
Using the following query below, I was able to achieve what I want but as you can see, it's hard coding back the past 5 months so if I wanted to go back 12 months, I'd have to add in more code.
DECLARE #5MonthAgo date = CAST(DATEADD(MONTH, -5, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -5, GETDATE())) AS DATE)
DECLARE #4MonthAgo date = CAST(DATEADD(MONTH, -4, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -4, GETDATE())) AS DATE)
DECLARE #3MonthAgo date = CAST(DATEADD(MONTH, -3, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -3, GETDATE())) AS DATE)
DECLARE #2MonthAgo date = CAST(DATEADD(MONTH, -2, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -2, GETDATE())) AS DATE)
DECLARE #1MonthAgo date = CAST(DATEADD(MONTH, -1, GETDATE()) + 1 - DATEPART(DAY, DATEADD(MONTH, -1, GETDATE())) AS DATE)
DECLARE #CurrentMonth date = CAST(GETDATE() + 1 - DATEPART(DAY, GETDATE()) AS DATE)
-- Table to return grouped and sum data
DECLARE #StatsTable TABLE ([Month] DATE,
[Total Amount] DECIMAL(18,2),
[Total Count] INT
)
-- Temporary table to hold onto data batch - so table isn't used later on
DECLARE #TempGenTable TABLE ([Id] INT,
[Date] DATETIME,
[Lines] INT NULL,
[Amount] DECIMAL(18, 2) NULL
)
INSERT INTO #TempGenTable
SELECT
Id, Date, Lines, Amount
FROM
TallyTable
WHERE
Date >= #5MonthAgo
INSERT INTO #StatsTable
SELECT
#5MonthAgo,
COALESCE((SELECT SUM(Amount)
FROM #TempGenTable
WHERE Date >= #5MonthAgo AND Date < #4MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0),
COALESCE((SELECT COUNT(Id)
FROM #TempGenTable
WHERE Date >= #5MonthAgo AND Date < #4MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0)
UNION
SELECT
#4MonthAgo,
COALESCE((SELECT SUM(Amount)
FROM #TempGenTable
WHERE Date >= #4MonthAgo AND Date < #3MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0),
COALESCE((SELECT COUNT(Id)
FROM #TempGenTable
WHERE Date >= #4MonthAgo AND Date < #3MonthAgo
GROUP BY DATEADD(MONTH, DATEDIFF(MONTH, 0, Date), 0)), 0)
...
Is there an easier way to be able to get the above data with more flexibility in the number of months?
Is it better to just have the query pass in a month variable and it checks just the current month and have a loop within the controller to go back x number of months?
I would generate the data using a recursive CTE and then use left join:
with months as (
select datefromparts(year(getdate()), month(getdate()), 1) as month_start, 5 as n
union all
select dateadd(month, -1, month_start), n - 1
from months
where n > 0
)
select m.month_start, count(s.id), sum(s.amount)
from months m left join
#StatsTable s
on m.month_start = s.month
group by m.month_start
order by m.month_start;
You haven't provided sample data, so I'm not sure what s.month looks like. You might want the join condition to be:
on s.month >= m.month_start and s.month < dateadd(month, 1, m.month_start)
Below is a set-based method to generate the needed monthly periods:
--sample data
CREATE TABLE dbo.TallyTable (
Id int
, Date datetime
, Lines int
, Amount decimal(18, 2)
);
INSERT INTO dbo.TallyTable
VALUES
(1, '2017-12-05', 1, 50.00)
,(2, '2017-12-06', 1, 150.00)
,(3, '2018-01-10', 1, 100.00)
,(4, '2018-01-11', 1, 100.00)
,(5, '2018-01-12', 1, 100.00)
,(6, '2018-03-15', 1, 225.00)
,(7, '2018-03-15', 1, 25.00)
,(8, '2018-03-15', 1, 50.00)
,(9, '2018-04-20', 1, 100.00);
GO
DECLARE #Months int = 5; --number of historical months
WITH
t10 AS (SELECT n FROM (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) t(n))
,t100 AS (SELECT ROW_NUMBER() OVER (ORDER BY (SELECT 0)) - 1 AS num FROM t10 AS a CROSS JOIN t10 AS b)
, periods AS (SELECT
CONVERT(varchar(7), DATEADD(month, DATEDIFF(month, '', GETDATE()) - num, ''),121) AS Month
, DATEADD(month, DATEDIFF(month, '', CAST(GETDATE() AS date)) - num, '') AS PeriodStart
, DATEADD(month, DATEDIFF(month, '', CAST(GETDATE() AS date)) - num + 1, '') AS NextPeriodStart
FROM t100
WHERE num <= #Months
)
SELECT periods.Month, COALESCE(SUM(Amount), 0) AS TotalAmount, COALESCE(COUNT(ID), 0) AS TotalCount
FROM periods
LEFT JOIN dbo.TallyTable ON
TallyTable.Date >= PeriodStart
AND TallyTable.Date < NextPeriodStart
GROUP BY periods.Month
ORDER BY periods.Month;

How to get list of 2nd and 4th Saturday dates in SQL Server?

I am almost a newbie to writing SQL queries.
In the context of SQL Server, how to get list of 2nd and 4th Saturday dates
in the year 2016?
Done as a derived table simply to show the logic but you can reduce if you prefer:
select *
from (
select d2016,
datename( weekday, d2016 ) as wkdy,
row_number( ) over ( partition by datepart( month, d2016 ), datename( weekday, d2016 ) order by d2016 ) as rn_dy_mth
from (
select dateadd( day, rn, cast( '2016-01-01' as date ) ) as d2016
from (
select row_number() over( order by object_id ) - 1 as rn
from sys.columns
) as rn
) as dy
) as dy_mth
where rn_dy_mth in ( 2, 4 )
and wkdy = 'Saturday'
order by d2016
--DEFINE LIMITS FOR DAY
DECLARE #TODATE DATETIME, #FROMDATE DATETIME
SET #FROMDATE ='2010-01-01'
SET #TODATE = '2017-12-31'
;WITH DATESEQUENCE( [DATE] ) AS
(
SELECT #FROMDATE AS [DATE]
UNION ALL
SELECT DATEADD(DAY, 1, [DATE])
FROM DATESEQUENCE
WHERE DATE < #TODATE
)
, DATESATURDAY AS
(SELECT CAST(CAST(YEAR([DATE]) AS VARCHAR)+
(CASE WHEN DATEPART(M,[DATE])<=9 THEN '0'+CAST(DATEPART(M,[DATE]) AS VARCHAR)
ELSE CAST(DATEPART(M,[DATE]) AS VARCHAR) END ) AS NUMERIC) AS MONTH_ID
,CONVERT(VARCHAR,[DATE],106) AS DAY_DESC
,UPPER(DATENAME(DW,[DATE]))AS DAY_NAME
FROM DATESEQUENCE )
,SECOND_FOURTH_SATURDAY AS
(SELECT *
,ROW_NUMBER() OVER (PARTITION BY MONTH_ID ORDER BY DAY_NAME) FALL_IN
FROM DATESATURDAY
WHERE DAY_NAME='SATURDAY')
SELECT * FROM SECOND_FOURTH_SATURDAY
WHERE FALL_IN IN(2,4)
OPTION (MAXRECURSION 10000)
You can get any Saturday of a month using the Following Query in SQL.
Here I'm Getting on Current Date, You can set your own selected date to get a Specific month Saturday
select DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0,getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0)) as FirstSaturday,
DATEADD(dd,7,DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) as SecondSaturday,
DATEADD(dd,14,DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) as ThirdSaturday,
DATEADD(dd,21,DATEADD(dd, (14 - ##DATEFIRST - DATEPART(dw, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) % 7, DATEADD(MONTH, DATEDIFF(mm, 0, getdate()), 0))) as LastSaturday

Reducing an extensive Query

I am compiling historical data on work tickets from our db. I am using the last day of the month for the past 12 months. On that date I want to see how many tickets were open (datecreated before or equal to last day of month and dateclose after last day or null). How many of those tickets had been open for more than 30 days as of the last day of the month, and how many tickets were closed during that month.
My query returns 4 values for each of the previous 12 months. I developed a query where I gathered the data for one month at a time and then used Union to get the next month and so forth.
I am now attempting to develop a query which does not need a Union for each month of data collected. Here is a sample month.
Select Convert(Varchar,
DATEADD(day,
-1,
DATEADD(mm, DATEDIFF(m, 0, GETDATE()) - 12, 0)),
101) as [ DateRun ],
t1. [ data1 ],
sum(t2. [ data2 ] + t3. [ data3 ]) as [ Total Open ],
(t1. [ data1 ] + 0.0) /
sum((t2. [ data2 ] + 0.0) + (t3. [ data3 ] + 0.0)) as [ Percent Aged Over 30 Days ]
From (Select count(*) as [ data1 ]
From (Select s.ticketnumber, s.datecreated, s.dateclosed
from mydb2 i
inner join mydb1 s
on i.ticketNumber = s.ticketNumber
Where datediff(dd,
s.dateCreated,
DATEADD(day,
-1,
DATEADD(mm,
DATEDIFF(m, 0, GETDATE()) - 12,
0))) > '30'
AND (s.dateclosed is null OR
s.dateclosed >=
DATEADD(day,
-1,
DATEADD(mm, DATEDIFF(m, 0, GETDATE()) - 12, 0)))
Group by s.ticketNumber, s.datecreated, s.dateclosed) as tb1) as t1,
(Select count(*) as [ data2 ]
From (Select s.ticketnumber, s.datecreated, s.dateclosed
from mydb2 i
inner join mydb1 s
on i.ticketNumber = s.ticketNumber
Where s.datecreated <
DATEADD(day,
-1,
DATEADD(mm, DATEDIFF(m, 0, GETDATE()) - 12, 0))
AND (s.dateclosed is null OR
s.dateclosed >=
DATEADD(day,
-1,
DATEADD(mm, DATEDIFF(m, 0, GETDATE()) - 12, 0)))
Group by s.ticketNumber, s.datecreated, s.dateclosed) as tb2) as t2,
(Select count(*) as [ data3 ]
From (Select s.ticketnumber, s.datecreated, s.dateclosed
from mydb2 i
inner join mydb1 s
on i.ticketNumber = s.ticketNumber
Where s.dateclosed >
DATEADD(day,
-1,
DATEADD(mm, DATEDIFF(m, 0, GETDATE()) - 13, 1))
AND s.dateclosed <
DATEADD(day,
-1,
DATEADD(mm, DATEDIFF(m, 0, GETDATE()) - 12, 0))
Group by s.ticketNumber, s.datecreated, s.dateclosed) as tb3) as t3
Group by t1. [ data1 ]
Through research I was able to get the past 12 months last day with the following code, but I have not been able to update the code above so that I don't need 12 Unions.
Select dateadd(month, 1 + datediff(month, 0, s.datecreated), -1) as [ Date Run ]
from mydb1 s
Where s.datecreated >
DATEADD(day, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()) - 12, 0))
and s.datecreated <
DATEADD(day, -1, DATEADD(mm, DATEDIFF(m, 0, GETDATE()), 0))
Group by dateadd(month, 1 + datediff(month, 0, s.datecreated), -1)
Order by 1
You might try generating the months using a CTE, use that as the basis for your query, then run the aggregates as subqueries. In other words, something like this:
with Months( ClosingDate, n ) as
(
select DATEADD(dd, -1, DATEADD(MONTH, DATEDIFF(MONTH, 0, GETDATE()), 0)) as ClosingDate, 1 as n
union all
select DATEADD(dd, -1, DATEADD(mm, -1, DATEADD(dd, 1, ClosingDate))), n + 1
from Months
where n < 12
)
select DATENAME(mm, m.ClosingDate) MonthLabel, DATEADD(dd, 1 - DATEPART(dd, m.ClosingDate), m.ClosingDate) OpeningDate, m.ClosingDate,
ISNULL((select COUNT(*)
from mydb1 s
where s.dateCreated < DATEADD(dd, -29, m.ClosingDate)
and (s.dateClosed is null or s.dateClosed >= DATEADD(dd, 1, m.ClosingDate))
), 0) [Total Open 30+ Days]
from Months m
For clarity I included only one of the aggregates and omitted your joins and grouping.