SQL - creating date range - sql

I am using the following follow script to show me the cap_date and max_capacity in the future and ... and sub-queries to show me the last_date and last_qty where older than the first select statement.
select
trunc(gp.cap_date) cap_date, gp.max_capacity,
(select max(trunc(gp1.cap_date))
from GPS_CAPACITY gp1
where gp.plant = gp1.plant
and gp.work_center_no = gp1.work_center_no
and gp1.cap_date = (select max(gp2.cap_date)
from GPS_CAPACITY gp2
where gp.plant = gp2.plant
and gp.work_center_no = gp2.work_center_no
and gp2.cap_date < gp.cap_date)) last_date,
(select max(gp1.max_capacity)
from GPS_CAPACITY gp1
where gp.plant = gp1.plant
and gp.work_center_no = gp1.work_center_no
and gp1.cap_date = (select max(gp2.cap_date)
from GPS_CAPACITY gp2
where gp.plant = gp2.plant
and gp.work_center_no = gp2.work_center_no
and gp2.cap_date < gp.cap_date)) last_qty
from
GPS_CAPACITY gp
where
gp.plant = 'W'
and gp.work_center_no = 'HPKG'
and trunc(gp.cap_date) > trunc(sysdate)
Output from this script looks like ...
... what I would like is to do is create a date list starting from the 'last_date' and show a qty for each date equal to last_qty; once the date list reaches the 'cap_date' qty should change to the max_capacity (the dates should run 7 days after the 'cap_date', i.e.
Any ideas?
Thanks

First create a cal table containing the range of dates of interest. Lets call that table cal with one column dt of type date. Assume your table above is called table_cap
Now do a
select cal.dt, case when cal.dt<cap_date then qty else max_capacity end
from cal
inner join table_cap on
(table_cap.last_date <= cal.dt
and cal.dt < adddate(capdate, interval 7 day )

Related

SELECT list expression references column integration_start_date which is neither grouped nor aggregated at

I'm facing an issue with the following query. It gave me this error [SELECT list expression references column integration_start_date which is neither grouped nor aggregated at [34:63]]. In particular, it points to the first 'when' in the result table, which I don't know how to fix. This is on BigQuery if that helps. I see everything is written correctly or I could be wrong. Seeking for help.
with plan_data as (
select format_date("%Y-%m-%d",last_day(date(a.basis_date))) as invoice_date,
a.sponsor_id as sponsor_id,
b.company_name as sponsor_name,
REPLACE(SUBSTR(d.meta,STRPOS(d.meta,'merchant_id')+12,13),'"','') as merchant_id,
a.state as plan_state,
date(c.start_date) as plan_start_date,
a.employee_id as square_employee_id,
date(
(select min(date)
from glproductionview.stats_sponsors
where sponsor_id = a.sponsor_id and sponsor_payroll_provider_identifier = 'square' and date >= c.start_date) )
as integration_start_date,
count(distinct a.employee_id) as eligible_pts_count, --pts that are in active plan and have payroll activities (payroll deductions) in the reporting month
from glproductionview.payroll_activities as a
left join glproductionview.sponsors as b
on a.sponsor_id = b.id
left join glproductionview.dc_plans as c
on a.plan_id = c.id
left join glproductionview.payroll_connections as d
on a.sponsor_id = d.sponsor_id and d.provider_identifier = 'rocket' and a.company_id = d.payroll_id
where a.payroll_provider_identifier = 'rocket'
and format_date("%Y-%m",date(a.basis_date)) = '2021-07'
and a.amount_cents > 0
group by 1,2,3,4,5,6,7,8
order by 2 asc
)
select invoice_date,
sponsor_id,
sponsor_name,
eligible_pts_count,
case
when eligible_pts_count <= 5 and date_diff(current_date(),integration_start_date, month) <= 12 then 20
when eligible_pts_count <= 5 and date_diff(current_date(),integration_start_date, month) > 12 then 15
when eligible_pts_count > 5 and date_diff(current_date(),integration_start_date, month) <= 12 then count(distinct square_employee_id)*4
when eligible_pts_count > 5 and date_diff(current_date(),integration_start_date, month) > 12 then count(distinct square_employee_id)*3
else 0
end as fees
from plan_data
group by 1,2,3,4;

CASE WHEN expression in oracle

I have built a CASE WHEN expression to show me when someone has no system transaction in the system under their user id for anything greater then 15 minutes.
case
when MOD_DATE_TIME > prior MOD_DATE_TIME+(1/96)
and user_id = prior user_id
then round((MOD_DATE_TIME - prior MOD_DATE_TIME)*1440,2)
else null
end as TIME_GAP
That above is the case when statement only. The full query is below:
select
user_id, MENU_OPTN_NAME, MOD_DATE_TIME,
case
when MOD_DATE_TIME > prior MOD_DATE_TIME+(1/96) and user_id = prior user_id then round((MOD_DATE_TIME - prior MOD_DATE_TIME)*1440,2)
else null
end as TIME_GAP
from
(select
ptt.user_id, MENU_OPTN_NAME, ptt.MOD_DATE_TIME,
row_number() over (partition by ptt.user_id order by ptt.MOD_DATE_TIME) seq
from PROD_TRKG_TRAN ptt
join cd_master cm on
ptt.cd_master_id = cm.cd_master_id
Where
MENU_OPTN_NAME = 'Cycle Cnt {Reserve}' --CHANGE BASED ON WHAT YOUR TRACKING... MENU NAMES AT THE BOTTOM
and ptt.user_id = 'LLEE1' --CHANGE BASED ON WHO YOU WANT TO TRACK FOR A GAP...
and cm.cd_master_id =
(select cd_master_id
from cd_master
where
co = '&CO'
and div = '&DIV')
and ptt.create_date_time >=
/*Today*/ trunc(sysdate)
--/*This Week*/ trunc(sysdate-(to_char(sysdate,'D')-1))
--/*This Month*/ trunc(sysdate)-(to_char(sysdate,'DD')-1)
--/*Date Range*/ '&FromDate' and ptt.create_date_time-1 < '&ToDate'
--group by ptt.user_id
)cc
CONNECT BY
user_id = prior user_id
and seq = prior seq+1
start with
seq = 1
What I want the query to do is in the CASE WHEN clause. I want it to account for the shift start time being 4pm, so if they don't do anything till 4:41PM then I would see that listed as a 41 min gap.

How to use a union to show rolled up values

I am using DB2 Syntax and hoping to use a UNION to create an additional row to show the rolled up values.
Rather than doing that the first portion of the union is merely naming the columns, whereas the data from the second union appears.
Here is the first portion
SELECT 'DRIVER ID' AS DRIVER_ID, 'NAME' AS NAME, 'PUNIT' AS PUNIT, 'PHONE' AS PHONE, 1767 AS TERMINAL_NUMBER, 'DRIVER TYPE' AS DRIVER_TYPE,
COALESCE((SELECT ROUND(DEC(SUM(CASE WHEN UPDATED_BY IN ('VISTAR','TM4WIN') THEN 1.00 ELSE 0.00 END))/COUNT(UPDATED_BY),2) FROM ODRSTAT, TLORDER L, DRIVER D WHERE DETAIL_LINE_ID = ORDER_ID AND STATUS_CODE IN ('ARRV#SHIP', 'ARRV#CONS', 'DEPT#SHIP', 'DEPT#CONS')
AND CURRENT_STATUS IN ('EDIBILLED','BILLD') AND L.PICK_UP_DRIVER = D.DRIVER_ID AND
D.TERMINAL_NUMBER IN (SELECT UNIQUE FIRST_FIELD_INSERT FROM SITE WHERE FAX_PHONE_NUMBER = :DIVISION) AND BILL_DATE BETWEEN CURRENT DATE - 1 MONTH AND CURRENT DATE AND ACTUAL_DELIVERY > ACTUAL_PICKUP +30 SECONDS),0) AVG_STATUS_UPDATE,
ROUND(((SELECT MAX(ODOMETER)-MIN(ODOMETER) FROM ODOHIST O
WHERE READINGDATE >= CURRENT DATE - 30 DAYS AND O.UNIT_ID IN (SELECT UNIT_ID FROM PUNIT WHERE ACTIVE_WHERE = 'D' AND FLEET_ID IN (SELECT UNIQUE USER5 FROM SITE WHERE FAX_PHONE_NUMBER = :DIVISION)))
/(SELECT NULLIF(SUM(T2.VOL_PFUEL),0) FROM FC_POS T2 INNER JOIN DRIVER D ON T2.DRIVER_ID = D.DRIVER_ID
WHERE D.TERMINAL_NUMBER IN (SELECT UNIQUE FIRST_FIELD_INSERT FROM SITE WHERE FAX_PHONE_NUMBER = :DIVISION) AND POS_DATE >= CURRENT DATE - 30 DAYS)),2) AVG_MPG,
(SELECT ROUND(AVG(TIMES),2) FROM (SELECT DELIVERY_DRIVER, ROUND(AVG(DEC((DAYS(CHECKIN_DATE) - DAYS(ACTUAL_DELIVERY)) *24 + (HOUR(CHECKIN_DATE) - HOUR(ACTUAL_DELIVERY)))/24),2) TIMES
FROM LIST_CHECKIN_AUDIT, LYNX.TLORDER WHERE LYNX.TLORDER.BILL_NUMBER = LIST_CHECKIN_AUDIT.BILL_NUMBER AND BILL_DATE >= CURRENT TIMESTAMP - 1 MONTH
AND LYNX.TLORDER.DOCUMENT_TYPE = 'INVOICE' AND ACTUAL_DELIVERY < CHECKIN_DATE AND ACTUAL_DELIVERY BETWEEN CURRENT TIMESTAMP - 6 MONTHS AND CURRENT TIMESTAMP + 3 DAYS
GROUP BY LYNX.TLORDER.BILL_NUMBER, DELIVERY_DRIVER) AVERAGES WHERE AVERAGES.DELIVERY_DRIVER IN (SELECT DRIVER_ID FROM DRIVER WHERE ACTIVE_IN_DISP = 'True' AND TERMINAL_NUMBER IN (SELECT UNIQUE FIRST_FIELD_INSERT FROM SITE WHERE FAX_PHONE_NUMBER = :DIVISION))) AS AVG_DAYS_TO_SCAN,
CAST(SUM(CASE WHEN VARCHAR(COALESCE((SELECT DATA FROM CUSTOM_DATA WHERE SRC_TABLE_KEY = DRIVER_ID AND CUSTDEF_ID = '50'),'False' ),10) = 'True' THEN 1 ELSE 0 END) AS VARCHAR(10)) AS DRIVE_AXLE,
(SELECT COUNT(UNIQUE A.BILL_NUMBER) FROM LIST_CHECKIN_AUDIT A INNER JOIN TLORDER T ON T.BILL_NUMBER = A.BILL_NUMBER
WHERE CURRENT_STATUS IN ('EDIBILLED','BILLD') AND COALESCE(PICK_UP_DRIVER,DELIVERY_DRIVER) IN (SELECT DRIVER_ID FROM DRIVER WHERE ACTIVE_IN_DISP = 'True'
AND TERMINAL_NUMBER IN (SELECT UNIQUE FIRST_FIELD_INSERT FROM SITE WHERE FAX_PHONE_NUMBER = :DIVISION)) AND BILL_DATE >= CURRENT DATE - 1 MONTH AND A.DOCUMENT_TYPE = 'DABL') AS DRIVERAXLE_SUBMISSIONS
FROM DRIVER WHERE ACTIVE_IN_DISP = 'True'
AND TERMINAL_NUMBER IN (SELECT UNIQUE FIRST_FIELD_INSERT FROM SITE WHERE FAX_PHONE_NUMBER = :DIVISION)
UNION ALL
SELECT DRIVER_ID, NAME, DEFAULT_PUNIT AS PUNIT, VARCHAR(USER9,12) AS PHONE, TERMINAL_NUMBER, DRIVER_TYPE,
COALESCE((SELECT ROUND(DEC(SUM(CASE WHEN UPDATED_BY IN ('VISTAR','TM4WIN') THEN 1.00 ELSE 0.00 END))/COUNT(UPDATED_BY),2) FROM ODRSTAT, TLORDER L WHERE DETAIL_LINE_ID = ORDER_ID AND STATUS_CODE IN ('ARRV#SHIP', 'ARRV#CONS', 'DEPT#SHIP', 'DEPT#CONS')
AND CURRENT_STATUS IN ('EDIBILLED','BILLD') AND L.PICK_UP_DRIVER = DRIVER_ID AND BILL_DATE BETWEEN CURRENT DATE - 1 MONTH AND CURRENT DATE AND ACTUAL_DELIVERY > ACTUAL_PICKUP +30 SECONDS),0) AS STATUS_UPDATE_PERCENT,
ROUND(((SELECT MAX(ODOMETER)-MIN(ODOMETER) FROM ODOHIST O
WHERE READINGDATE >= CURRENT DATE - 30 DAYS AND O.UNIT_ID = DEFAULT_PUNIT)/(SELECT NULLIF(SUM(T2.VOL_PFUEL),0) FROM FC_POS T2 WHERE T2.DRIVER_ID = DRIVER.DRIVER_ID AND POS_DATE >= CURRENT DATE - 30 DAYS)),2) AS MPG_30DAYS,
(SELECT ROUND(AVG(TIMES),2) FROM (SELECT DELIVERY_DRIVER, ROUND(AVG(DEC((DAYS(CHECKIN_DATE) - DAYS(ACTUAL_DELIVERY)) *24 + (HOUR(CHECKIN_DATE) - HOUR(ACTUAL_DELIVERY)))/24),2) TIMES
FROM LIST_CHECKIN_AUDIT, LYNX.TLORDER WHERE LYNX.TLORDER.BILL_NUMBER = LIST_CHECKIN_AUDIT.BILL_NUMBER AND BILL_DATE >= CURRENT TIMESTAMP - 1 MONTH
AND LYNX.TLORDER.DOCUMENT_TYPE = 'INVOICE' AND ACTUAL_DELIVERY < CHECKIN_DATE AND ACTUAL_DELIVERY BETWEEN CURRENT TIMESTAMP - 6 MONTHS AND CURRENT TIMESTAMP + 3 DAYS
GROUP BY LYNX.TLORDER.BILL_NUMBER, DELIVERY_DRIVER) AVERAGES WHERE AVERAGES.DELIVERY_DRIVER = DRIVER.DRIVER_ID)
AVG_DAYS_TO_SCAN,
VARCHAR(COALESCE((SELECT DATA FROM CUSTOM_DATA WHERE SRC_TABLE_KEY = DRIVER_ID AND CUSTDEF_ID = '50'),'False' ),10) AS DRIVEAXLE,
(SELECT COUNT(UNIQUE A.BILL_NUMBER) FROM LIST_CHECKIN_AUDIT A INNER JOIN TLORDER T ON T.BILL_NUMBER = A.BILL_NUMBER
WHERE CURRENT_STATUS IN ('EDIBILLED','BILLD') AND COALESCE(PICK_UP_DRIVER,DELIVERY_DRIVER) = DRIVER_ID AND BILL_DATE >= CURRENT DATE - 1 MONTH AND A.DOCUMENT_TYPE = 'DABL') AS DRIVERAXLE_SUBMISSIONS_1_MONTH
FROM DRIVER WHERE ACTIVE_IN_DISP = 'True'
AND TERMINAL_NUMBER IN (SELECT UNIQUE FIRST_FIELD_INSERT FROM SITE WHERE FAX_PHONE_NUMBER = :DIVISION)
I've not looked at your code...given the lack of formatting, it's not easy to follow.
However, when I've used UNION in the past to provide rolled up values, I've included extra columns that provides a way for me to differentiate between details and totals. These extra columns is also used as the first column to ORDER BY
Example:
select
digits(HCUSNR) as Cust_Num,
CCUSNM,
char(HINVNR),
hinamt,
-- Control fields
' ' concat digits(HCMPCL),
case
when HTRCDE in ('A', 'E', 'R')
then ' LVL3'
else ' LVL1'
end,
HCUSNR, DDVDSC, HDIVSN
UNION ALL
select
' ',
'Daily Invoice Total',
' ',
sum(hinamt),
-- Control Fields
' ' concat digits(HCMPCL), ' LVL2', 0, ' ', HDIVSN
group by
HDIVSN, HCMPCL
--Following order by applies to entire results set
order by 5,6,7,8,9
But the above was written close to 20 years ago...
If I needed to do it today, I'd use the grouping sets, rollup, and cube functionality that IBM has added to the DB.
What platform and version of DB2 are you using? Are grouping sets, rollup and/or cube an option?

How do I use calendar exceptions to generate accurate schedules using GTFS?

I'm having trouble figuring out the GTFS query to obtain the next 20 schedules for a given stop ID and a given direction.
I know the stop ID, the trip direction ID, the time (now) and the date (today)
I wrote
SELECT DISTINCT ST.departure_time FROM stop_times ST
JOIN trips T ON T._id = ST.trip_id
JOIN calendar C ON C._id = T.service_id
JOIN calendar_dates CD on CD.service_id = T.service_id
WHERE ST.stop_id = 3377699724118483
AND T.direction_id = 0
AND ST.departure_time >= "16:00:00"
AND
(
( C.start_date <= 20140607 AND C.end_date >= 20140607 AND C.saturday= 1 ) // regular service today
AND ( ( CD.date != 20140607 ) // no exception today
OR ( CD.date = 20140607 AND CD.exception_type = 1 ) // or ADDED exception today
)
)
ORDER BY stopTimes.departure_time LIMIT 20
This results in no record being found.
If a remove the last part, dealgin with the CD tables (i.e. the removed or added exceptions), it works perfectly fine.
So I think I'm miswriting the check on the exceptions.
As written above with // comments, I want to check that
today is in a regular service (from checking the calendar table)
there is no removal exception for today (or in this case the trips corresponding to this service id are not included in the computation)
if there is added exception for today, the corresponding trips shall be included in the computation
can you help me with that ?
I'm fairly certain it's not possible to do what you're trying to do with only a single SELECT statement, due to the design of the calendar and calendar_dates tables.
What I do is use a second, inner query to build the set of active service IDs on the requested date, then join the outer query against this set to include only results relevant for that date. Try this:
SELECT DISTINCT ST.departure_time FROM stop_times ST
JOIN trips T ON T._id = ST.trip_id
JOIN (SELECT _id FROM calendar
WHERE start_date <= 20140607
AND end_date >= 20140607
AND saturday = 1
UNION
SELECT service_id FROM calendar_dates
WHERE date = 20140607
AND exception_type = 1
EXCEPT
SELECT service_id FROM calendar_dates
WHERE date = 20140607
AND exception_type = 2
) ASI ON ASI._id = T.service_id
WHERE ST.stop_id = 3377699724118483
AND T.direction_id = 0
AND ST.departure_time >= "16:00:00"
ORDER BY ST.departure_time
LIMIT 20

SQL Query in CRM Report

A "Case" in CRM has a field called "Status" with four options.
I'm trying to
build a report in CRM that fills a table with every week of the year (each row is a different week), and then counts the number of cases that have each Status option (the columns would be each of the Status options).
The table would look like this
Status 1 Status 2 Status 3
Week 1 3 55 4
Week 2 5 23 5
Week 3 14 11 33
So far I have the following:
SELECT
SUM(case WHEN status = 1 then 1 else 0 end) Status1,
SUM(case WHEN status = 2 then 1 else 0 end) Status2,
SUM(case WHEN status = 3 then 1 else 0 end) Status3,
SUM(case WHEN status = 4 then 1 else 0 end) Status4,
SUM(case WHEN status = 5 then 1 else 0 end) Status5
FROM [DB].[dbo].[Contact]
Which gives me the following:
Status 1 Status 2 Status 3
2 43 53
Now I need to somehow split this into 52 rows for the past year and filter these results by date (columns in the Contact table). I'm a bit new to SQL queries and CRM - any help here would be much appreciated.
Here is a SQLFiddle with my progress and sample data: http://sqlfiddle.com/#!2/85b19/1
Sounds like you want to group by a range. The trick is to create a new field that represents each range (for you one per year) and group by that.
Since it also seems like you want an infinite range of dates, marc_s has a good summary for how to do the group by trick with dates in a generic way: SQL group by frequency within a date range
So, let's break this down:
You want to make a report that shows, for each contact, a breakdown, week by week, of the number of cases registered to that contact, which is divided into three columns, one for each StateCode.
If this is the case, then you would need to have 52 date records (or so) for each contact. For calendar like requests, it's always good to have a separate calendar table that lets you query from it. Dan Guzman has a blog entry that creates a useful calendar table which I'll use in the query.
WITH WeekNumbers AS
(
SELECT
FirstDateOfWeek,
-- order by first date of week, grouping calendar year to produce week numbers
WeekNumber = row_number() OVER (PARTITION BY CalendarYear ORDER BY FirstDateOfWeek)
FROM
master.dbo.Calendar -- created from script
GROUP BY
FirstDateOfWeek,
CalendarYear
), Calendar AS
(
SELECT
WeekNumber =
(
SELECT
WeekNumber
FROM
WeekNumbers WN
WHERE
C.FirstDateOfWeek = WN.FirstDateOfWeek
),
*
FROM
master.dbo.Calendar C
WHERE
CalendarDate BETWEEN '1/1/2012' AND getutcdate()
)
SELECT
C.FullName,
----include the below if the data is necessary
--Cl.WeekNumber,
--Cl.CalendarYear,
--Cl.FirstDateOfWeek,
--Cl.LastDateOfWeek,
'Week: ' + CAST(Cl.WeekNumber AS VARCHAR(20))
+ ', Year: ' + CAST(Cl.CalendarYear AS VARCHAR(20)) WeekNumber
FROM
CRM.dbo.Contact C
-- use a cartesian join to produce a table list
CROSS JOIN
(
SELECT
DISTINCT WeekNumber,
CalendarYear,
FirstDateOfWeek,
LastDateOfWeek
FROM
Calendar
) Cl
ORDER BY
C.FullName,
Cl.WeekNumber
This is different from the solution Ben linked to because Marc's query only returns weeks where there is a matching value, whereas you may or may not want to see even the weeks where there is no activity.
Once you have your core tables of contacts split out week by week as in the above (or altered for your specific time period), you can simply add a subquery for each StateCode to see the breakdown in columns as in the final query below.
WITH WeekNumbers AS
(
SELECT
FirstDateOfWeek,
WeekNumber = row_number() OVER (PARTITION BY CalendarYear ORDER BY FirstDateOfWeek)
FROM
master.dbo.Calendar
GROUP BY
FirstDateOfWeek,
CalendarYear
), Calendar AS
(
SELECT
WeekNumber =
(
SELECT
WeekNumber
FROM
WeekNumbers WN
WHERE
C.FirstDateOfWeek = WN.FirstDateOfWeek
),
*
FROM
master.dbo.Calendar C
WHERE
CalendarDate BETWEEN '1/1/2012' AND getutcdate()
)
SELECT
C.FullName,
--Cl.WeekNumber,
--Cl.CalendarYear,
--Cl.FirstDateOfWeek,
--Cl.LastDateOfWeek,
'Week: ' + CAST(Cl.WeekNumber AS VARCHAR(20)) +', Year: ' + CAST(Cl.CalendarYear AS VARCHAR(20)) WeekNumber,
(
SELECT
count(*)
FROM
CRM.dbo.Incident I
INNER JOIN CRM.dbo.StringMap SM ON
I.StateCode = SM.AttributeValue
INNER JOIN
(
SELECT
DISTINCT ME.Name,
ME.ObjectTypeCode
FROM
CRM.MetadataSchema.Entity ME
) E ON
SM.ObjectTypeCode = E.ObjectTypeCode
WHERE
I.ModifiedOn >= Cl.FirstDateOfWeek
AND I.ModifiedOn < dateadd(day, 1, Cl.LastDateOfWeek)
AND E.Name = 'incident'
AND SM.AttributeName = 'statecode'
AND SM.LangId = 1033
AND I.CustomerId = C.ContactId
AND SM.Value = 'Active'
) ActiveCases,
(
SELECT
count(*)
FROM
CRM.dbo.Incident I
INNER JOIN CRM.dbo.StringMap SM ON
I.StateCode = SM.AttributeValue
INNER JOIN
(
SELECT
DISTINCT ME.Name,
ME.ObjectTypeCode
FROM
CRM.MetadataSchema.Entity ME
) E ON
SM.ObjectTypeCode = E.ObjectTypeCode
WHERE
I.ModifiedOn >= Cl.FirstDateOfWeek
AND I.ModifiedOn < dateadd(day, 1, Cl.LastDateOfWeek)
AND E.Name = 'incident'
AND SM.AttributeName = 'statecode'
AND SM.LangId = 1033
AND I.CustomerId = C.ContactId
AND SM.Value = 'Resolved'
) ResolvedCases,
(
SELECT
count(*)
FROM
CRM.dbo.Incident I
INNER JOIN CRM.dbo.StringMap SM ON
I.StateCode = SM.AttributeValue
INNER JOIN
(
SELECT
DISTINCT ME.Name,
ME.ObjectTypeCode
FROM
CRM.MetadataSchema.Entity ME
) E ON
SM.ObjectTypeCode = E.ObjectTypeCode
WHERE
I.ModifiedOn >= Cl.FirstDateOfWeek
AND I.ModifiedOn < dateadd(day, 1, Cl.LastDateOfWeek)
AND E.Name = 'incident'
AND SM.AttributeName = 'statecode'
AND SM.LangId = 1033
AND I.CustomerId = C.ContactId
AND SM.Value = 'Canceled'
) CancelledCases
FROM
CRM.dbo.Contact C
CROSS JOIN
(
SELECT
DISTINCT WeekNumber,
CalendarYear,
FirstDateOfWeek,
LastDateOfWeek
FROM
Calendar
) Cl
ORDER BY
C.FullName,
Cl.WeekNumber