I have two tables: Staff and Hours.
Staff(200+ rows) with:
Staff_ID, Name, Position
each staff member only appears once in this table
Hours (1000+ rows) with:
Staff_ID, Hours, Amount, BillableFlag, Office, DatePeriod
each staff member appears many times in this table
I need a query that pulls in all Staff from the Staff table with position = 'Assistant' and the Hours and Amount columns from the Hours table summed twice each with different logic for each sum.
Something like this ( it's a query with some plain english to help with the explanation ):
select s.name,
sum(h.hours) as 'Hours_Not_Billable' --[NEED IT TO SUM ONLY HOURS WHERE h.BILLABLEFLAG <> 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER],
sum(h.amount) as 'Amount_Not_Billable' --[NEED IT TO SUM ONLY AMOUNT WHERE h.BILLABLEFLAG <> 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER],
sum(h.hours) as 'Hours_Billable' --[NEED IT TO SUM ONLY HOURS WHERE h.BILLABLEFLAG = 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER],
sum(h.amount) as 'Amount_Billable --[NEED IT TO SUM ONLY HOURS WHERE h.BILLABLEFLAG = 'Y', h.office = '2', h.period = 'Q3' AND ONLY DO IT FOR EACH STAFF MEMBER]'
from Staff S
left join Hours H on S.Staff_ID = H.Staff_ID
where s.position = 'Assistant'
group by s.name
Help much appreciated!
Thank you
Use conditional aggregation. The idea is to put a case expression inside the sum(), that filters out with values are taken into account.
Your pseudo-code would translate as:
select
s.name,
sum(case when h.billableflag <> 'Y' then h.hours else 0 end) hours_not_billable,
sum(case when h.billableflag <> 'Y' then h.amount else 0 end) amount_not_billable,
sum(case when h.billableflag = 'Y' then h.hours else 0 end) hours_billable,
sum(case when h.billableflag = 'Y' then h.amount else 0 end) amount_billable
from staff s
left join hours h
on s.staff_id = h.staff_id and h.office = 2 and h.period = 'Q3'
where s.position = 'Assistant'
group by s.name
Note: most of the conditions are common to all expressions, so I moved them to the on clause of the left join.
You can use CASE WHEN within SUM() aggregation function as follows
select
s.name,
sum(case when h.BILLABLEFLAG <> 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.hours else null end) as 'Hours_Not_Billable',
sum(case when h.BILLABLEFLAG <> 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.amount else null end) as 'Amount_Not_Billable',
sum(case when h.BILLABLEFLAG = 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.hours else null end) as 'Hours_Billable',
sum(case when h.BILLABLEFLAG = 'Y' and h.office = '2' and h.DatePeriod = 'Q3' then h.amount else null end ) as 'Amount_Billable'
from Staff S
left join Hours H on S.Staff_ID = H.Staff_ID
where s.position = 'Assistant'
group by s.name
I'm trying to pull a report of the previous year's usage based on Year and Period(month)
I adjusted the top line to add a filter for AND demand_period.year_for_period = YEAR(getdate()) but then realized that it will also remove the possibility of last year's results.
Prior to adding the YEAR statement, it was providing full sums of the usage for all years, broken down by month.
Here's what I have so far:
SELECT (inv_mast.item_id) as [Item ID]
,inv_mast.item_desc as [Item Description]
,address.name as [Prim Supplier Name]
,SUM(CASE WHEN (demand_period.period = MONTH(getdate()) AND demand_period.year_for_period = YEAR(getdate()))THEN inv_period_usage ELSE 0 END) AS [Period1Usage]
,SUM(CASE WHEN demand_period.period = '2' THEN inv_period_usage ELSE 0 END) AS [Period2Usage]
,SUM(CASE WHEN demand_period.period = '3' THEN inv_period_usage ELSE 0 END) AS [Period3Usage]
,SUM(CASE WHEN demand_period.period = '4' THEN inv_period_usage ELSE 0 END) AS [Period4Usage]
,SUM(CASE WHEN demand_period.period = '5' THEN inv_period_usage ELSE 0 END) AS [Period5Usage]
,SUM(CASE WHEN demand_period.period = '6' THEN inv_period_usage ELSE 0 END) AS [Period6Usage]
,SUM(CASE WHEN demand_period.period = '7' THEN inv_period_usage ELSE 0 END) AS [Period7Usage]
,SUM(CASE WHEN demand_period.period = '8' THEN inv_period_usage ELSE 0 END) AS [Period8Usage]
,SUM(CASE WHEN demand_period.period = '9' THEN inv_period_usage ELSE 0 END) AS [Period9Usage]
,SUM(CASE WHEN demand_period.period = '10' THEN inv_period_usage ELSE 0 END) AS [Period10Usage]
,SUM(CASE WHEN demand_period.period = '11' THEN inv_period_usage ELSE 0 END) AS [Period11Usage]
,SUM(CASE WHEN demand_period.period = '12' THEN inv_period_usage ELSE 0 END) AS [Period12Usage]
FROM inv_mast
JOIN inv_loc ON inv_loc.inv_mast_uid = inv_mast.inv_mast_uid
JOIN inventory_supplier_x_loc ON inventory_supplier_x_loc.location_id = inv_loc.location_id
JOIN inventory_supplier ON inventory_supplier.inventory_supplier_uid = inventory_supplier_x_loc.inventory_supplier_uid
JOIN supplier ON supplier.supplier_id = inventory_supplier.supplier_id
JOIN address ON (address.id = supplier.supplier_id)
JOIN inv_period_usage ON inv_period_usage.location_id = inv_loc.location_id
JOIN demand_period ON (inv_period_usage.demand_period_uid = demand_period.demand_period_uid)
WHERE
(inv_loc.location_id = '100001')
AND (inventory_supplier_x_loc.primary_supplier = 'Y')
AND (inv_mast.item_id = '111')
GROUP BY item_id, item_desc, name
How could I edit the SELECT statements to include the last 12 months, including if they are in a previous year?
Thank you for your help!
Add this:
and demand_period.year_for_period >= DATEADD(month, -12, getdate())
I am trying to find a more compact code form and faster way to execute a query that requires (or at least I think requires) grouping by TWO case statements
I've tried using OVER PARTITION but can't seem to get the desired result
SELECT
CASE
WHEN AA.BUSINESS_SEGMENT LIKE 'YEPPERS%'
THEN 'YES'
ELSE 'NO'
END 'YZY',
CASE
WHEN MONTH(POI.EX_FACTORY_DATE) >= 1 AND MONTH(POI.EX_FACTORY_DATE) <=3
THEN
'Q1'
WHEN MONTH(POI.EX_FACTORY_DATE) >= 4 AND MONTH(POI.EX_FACTORY_DATE) <=6
THEN
'Q2'
WHEN MONTH(POI.EX_FACTORY_DATE) >= 7 AND MONTH(POI.EX_FACTORY_DATE) <=9
THEN
'Q3'
WHEN MONTH(POI.EX_FACTORY_DATE) >= 10 AND MONTH(POI.EX_FACTORY_DATE) <=12
THEN
'Q4'
END 'QTR',
SUM(POI.PO_ORDERED_QUANTITY) PO_QTY
FROM VW_PO_ITEM POI
LEFT JOIN VW_ARTICLE_ATTRIBUTES AA ON AA.ARTICLE = POI.MATERIAL
WHERE POI.DEL_INDICATOR <> 'L' AND POI.EX_FACTORY_DATE BETWEEN '7/1/2019' AND '12/31/2019' AND ((POI.SHIPPING_INSTRUCT='A2' AND AA.BUSINESS_SEGMENT NOT LIKE 'YEPPERS%') OR AA.BUSINESS_SEGMENT LIKE 'YEPPERS%')
GROUP BY
CASE
WHEN AA.BUSINESS_SEGMENT LIKE 'YEPPERS%'
THEN 'YES'
ELSE 'NO'
END,
CASE
WHEN MONTH(POI.EX_FACTORY_DATE) >= 1 AND MONTH(POI.EX_FACTORY_DATE) <=3
THEN
'Q1'
WHEN MONTH(POI.EX_FACTORY_DATE) >= 4 AND MONTH(POI.EX_FACTORY_DATE) <=6
THEN
'Q2'
WHEN MONTH(POI.EX_FACTORY_DATE) >= 7 AND MONTH(POI.EX_FACTORY_DATE) <=9
THEN
'Q3'
WHEN MONTH(POI.EX_FACTORY_DATE) >= 10 AND MONTH(POI.EX_FACTORY_DATE) <=12
THEN
'Q4'
END
--desired result (the query above does produce this)
YZY QTR PO_QTY
-------- ---- ---------------------------------------
NO Q4 389309
YES Q4 649842
YES Q3 843438
NO Q3 20146
I think better is use DATEPART(quarter
FROM MyTable
GROUP BY DATEPART(quarter, columndate)
Consider a CTE to handle unit level calculation before final aggregation, avoiding repetition. Also, look into DatePart to extract date parts from datetime fields:
WITH cte AS (
SELECT CASE
WHEN AA.BUSINESS_SEGMENT LIKE 'YEPPERS%'
THEN 'YES' ELSE 'NO'
END [YZY],
DATEPART(qq, POI.EX_FACTORY_DATE) AS [QTR],
POI.PO_ORDERED_QUANTITY
FROM VW_PO_ITEM POI
LEFT JOIN VW_ARTICLE_ATTRIBUTES AA
ON AA.ARTICLE = POI.MATERIAL
WHERE POI.DEL_INDICATOR <> 'L'
AND POI.EX_FACTORY_DATE BETWEEN '2019-07-01' AND '2019-12-31'
AND (
(POI.SHIPPING_INSTRUCT='A2'
AND AA.BUSINESS_SEGMENT NOT LIKE 'YEPPERS%')
OR
AA.BUSINESS_SEGMENT LIKE 'YEPPERS%'
)
)
SELECT [YZY], [QTR],
SUM(POI.PO_ORDERED_QUANTITY) AS PO_QTY
FROM cte
GROUP BY [YZY], [QTR]
I have a query that runs for 12 hours.
The query does left joins on 5 tables and reports on a bunch of monthly metrics. Here is the query:
SELECT DATEPART(YYYY,Referral_dt) AS RefYear, DATEPART(MM,Referral_dt) AS RefMonth,
CASE
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2013' AND '4/14/2013' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2013' AND '7/14/2013' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2013' AND '9/30/2013' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2013' AND '12/31/2013' THEN 'Q4'
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2014' AND '4/14/2014' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2014' AND '7/14/2014' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2014' AND '9/30/2014' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2014' AND '12/31/2014' THEN 'Q4'
ELSE 'X' END as RefQtr,
crm.salesstatuscode, crm.Referral_State, crm.lead_source, mp.mcc_desc, mp.mcc_industry, sr.manager_name, sr.payrollname,
sr.region as Sales_Region,sr.market as Sales_Market, sr.saleschannel as SalesChannel, Bk.SuperRegion_Name as Bank_SuperRegion,
Bk.Region_Name as Bank_Region ,Bk.Division_Name as Bank_Division,
sum(case when crm.referral_state = 'Won' then 1 else 0 end) as referrals_won, sum(sv.projected_profit) as prj_profit,
sum(case when mp.proposal_Date is null then 0 else 1 end) as proposals_created, sum(ac.signed_annual_volume) as total_signed_volume,
sum(case when ac.Acct_Act_Date is null then 0 else 1 end) as activated_accounts, COUNT(*) as referral_count
into moagg1
FROM kaiserver.dbKAI.dbo.Referrals_CRM CRM
LEFT JOIN (SELECT p.merchant_id, CAST(p.proposal_create_dt as date) as Proposal_Date, m.mcc_desc, m.mcc_industry
from kaiserver.[dbKAI].[dbo].[proposals] p
left join (SELECT mcc, mcc_desc, mcc_industry from kaiserver.[dbKAI].[dbo].[merchantcategorycode]) m
on p.mcc = m.mcc where datepart(yyyy,proposal_create_dt) in ('2013', '2014')) mp
ON crm.merchant_id = mp.merchant_id
LEFT JOIN (SELECT account_no, CAST(Account_Activate_dt as date) as Acct_Act_Date, signed_annual_volume, average_tkt
from kaiserver.[dbKAI].[dbo].[Account]
where current_ind=1 and datepart(yyyy,account_submit_dt) in ('2013', '2014')) ac
ON crm.account_no = ac.account_no
LEFT JOIN (SELECT e1.repid, e1.repcode, e1.payrollname, e1.salesmanager, e2.payrollname as manager_name,
e1.region,e1.market, e1.saleschannel
FROM [fdserver].fdms.[dbo].[tbl_reps] e1 LEFT JOIN [fdserver].fdms.[dbo].[tbl_reps] e2
ON e1.salesmanager = e2.repid
WHERE e1.market not like ('%TEST%') and e1.payrollname is not null and e1.region is not null and e1.market is not null) SR
ON CRM.Sales_Rep_Cd = SR.Repcode
LEFT JOIN (SELECT [AU_name], [AU_Code] ,[SuperRegion_Name], [Region_Name] ,[Division_Name],
[SubDivision_Name] ,[District_Name] ,[SubDistrict_Name]
FROM kaiserver.[dbKAI].[dbo].[BankAU_Hierarchy]
WHERE [Reporting_Interval_Id] = '201410') BK
ON CRM.referral_au = BK.AU_code
LEFT JOIN (select merchantnumber, projected_profit from kaiserver.[dbKAI].[dbo].[SoldVolumeDetail]) sv
ON crm.account_no = sv.merchantnumber
WHERE DATEPART(YYYY, Referral_dt) in ('2013', '2014')
AND (crm.salesstatuscode <> 'DUPL' or crm.salesstatuscode is null)
AND crm.lead_source not in ('Test Lead', 'Bank Lead Placeholder')
group by DATEPART(YYYY,Referral_dt), DATEPART(MM,Referral_dt), crm.Referral_State, crm.salesstatuscode, crm.lead_source, mp.mcc_desc,
mp.mcc_industry, sr.manager_name, sr.payrollname, sr.region,sr.market, sr.saleschannel, Bk.SuperRegion_Name, Bk.Region_Name ,Bk.Division_Name,
CASE
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2013' AND '4/14/2013' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2013' AND '7/14/2013' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2013' AND '9/30/2013' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2013' AND '12/31/2013' THEN 'Q4'
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2014' AND '4/14/2014' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2014' AND '7/14/2014' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2014' AND '9/30/2014' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2014' AND '12/31/2014' THEN 'Q4'
ELSE 'X' END
When I run the full query as above, it runs for 12 hours. But when I run the query for 1 month, it runs in 8 minutes. So I want to run the query for each month and append into one file. That should make this query run in 2-3 hours.
I can use union and copy the code 24 times but that doesn't seem like the best way to do it. Is there a more programattic way to do this?
UPDATE: I want to be able to run this query every day to update the latest month's numbers.
By the looks of the execution plan you posted I think you have a missing join predicate and are generating a ton of intermediate rows:
Here's the same query cleaned up slightly (CTEs instead of correlated subqueries and replaced the CASE statement with DATEPART(QUARTER)), it might make it easier to tell where your missing predicate is:
WITH
m as (SELECT mcc, mcc_desc, mcc_industry from kaiserver.[dbKAI].[dbo].[merchantcategorycode]),
mp as (SELECT p.merchant_id, CAST(p.proposal_create_dt as date) as Proposal_Date, m.mcc_desc, m.mcc_industry
from kaiserver.[dbKAI].[dbo].[proposals] p
left join m on p.mcc = m.mcc where datepart(yyyy,proposal_create_dt) in ('2013', '2014')),
ac as (SELECT account_no, CAST(Account_Activate_dt as date) as Acct_Act_Date, signed_annual_volume, average_tkt
from kaiserver.[dbKAI].[dbo].[Account]
where current_ind=1 and datepart(yyyy,account_submit_dt) in ('2013', '2014')),
sr as (SELECT e1.repid, e1.repcode, e1.payrollname, e1.salesmanager, e2.payrollname as manager_name, e1.region,e1.market, e1.saleschannel
FROM [fdserver].fdms.[dbo].[tbl_reps] e1
LEFT JOIN [fdserver].fdms.[dbo].[tbl_reps] e2 ON e1.salesmanager = e2.repid
WHERE e1.market not like ('%TEST%') and e1.payrollname is not null and e1.region is not null and e1.market is not null),
bk as (SELECT [AU_name], [AU_Code], [SuperRegion_Name], [Region_Name] ,[Division_Name], [SubDivision_Name], [District_Name], [SubDistrict_Name]
FROM kaiserver.[dbKAI].[dbo].[BankAU_Hierarchy]
WHERE [Reporting_Interval_Id] = '201410'),
sv as (select merchantnumber, projected_profit from kaiserver.[dbKAI].[dbo].[SoldVolumeDetail])
SELECT DATEPART(YYYY,Referral_dt) AS RefYear, DATEPART(MM,Referral_dt) AS RefMonth, DATEPART(QUARTER, Referral_dt) as RefQtr,
crm.salesstatuscode, crm.Referral_State, crm.lead_source, mp.mcc_desc, mp.mcc_industry, sr.manager_name, sr.payrollname,
sr.region as Sales_Region,sr.market as Sales_Market, sr.saleschannel as SalesChannel, Bk.SuperRegion_Name as Bank_SuperRegion,
Bk.Region_Name as Bank_Region ,Bk.Division_Name as Bank_Division,
sum(case when crm.referral_state = 'Won' then 1 else 0 end) as referrals_won, sum(sv.projected_profit) as prj_profit,
sum(case when mp.proposal_Date is null then 0 else 1 end) as proposals_created, sum(ac.signed_annual_volume) as total_signed_volume,
sum(case when ac.Acct_Act_Date is null then 0 else 1 end) as activated_accounts, COUNT(*) as referral_count INTO moagg1
FROM kaiserver.dbKAI.dbo.Referrals_CRM CRM
LEFT JOIN mp ON crm.merchant_id = mp.merchant_id
LEFT JOIN ac ON crm.account_no = ac.account_no
LEFT JOIN sr ON crm.sales_rep_cd = sr.repcode
LEFT JOIN bk ON crm.referral_au = ck.au_code
LEFT JOIN sv ON crm.account_no = sv.merchantnumber
WHERE DATEPART(YYYY, Referral_dt) in ('2013', '2014')
AND (crm.salesstatuscode <> 'DUPL' or crm.salesstatuscode is null)
AND crm.lead_source not in ('Test Lead', 'Bank Lead Placeholder')
group by DATEPART(YYYY,Referral_dt), DATEPART(MM,Referral_dt), crm.Referral_State, crm.salesstatuscode, crm.lead_source, mp.mcc_desc,
mp.mcc_industry, sr.manager_name, sr.payrollname, sr.region,sr.market, sr.saleschannel, Bk.SuperRegion_Name, Bk.Region_Name ,Bk.Division_Name,
DATEPART(QUARTER, Referral_dt)
I think this produces identical output and it should be faster. Also, you need to ensure every field that is used for a JOIN or in the WHERE clause is indexed.
SELECT
DATEPART(YYYY,Referral_dt) AS RefYear, DATEPART(MM,Referral_dt) AS RefMonth,
CASE
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2013' AND '4/14/2013' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2013' AND '7/14/2013' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2013' AND '9/30/2013' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2013' AND '12/31/2013' THEN 'Q4'
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2014' AND '4/14/2014' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2014' AND '7/14/2014' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2014' AND '9/30/2014' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2014' AND '12/31/2014' THEN 'Q4'
ELSE 'X' END as RefQtr,
crm.salesstatuscode, crm.Referral_State, crm.lead_source, m.mcc_desc, m.mcc_industry, e2.manager_name, e1.payrollname,
e1.region as Sales_Region,e1.market as Sales_Market, e1.saleschannel as SalesChannel, Bk.SuperRegion_Name as Bank_SuperRegion,
Bk.Region_Name as Bank_Region ,Bk.Division_Name as Bank_Division,
sum(case when crm.referral_state = 'Won' then 1 else 0 end) as referrals_won, sum(sv.projected_profit) as prj_profit,
sum(case when p.proposal_Date is null then 0 else 1 end) as proposals_created, sum(ac.signed_annual_volume) as total_signed_volume,
sum(case when ac.Acct_Act_Date is null then 0 else 1 end) as activated_accounts, COUNT(*) as referral_count
into moagg1
FROM kaiserver.dbKAI.dbo.Referrals_CRM CRM
LEFT kaiserver.[dbKAI].[dbo].[proposals] p ON crm.merchant_id = p.merchant_id
AND datepart(yyyy,p.proposal_create_dt) in ('2013', '2014')
left join kaiserver.[dbKAI].[dbo].[merchantcategorycode] m on p.mcc = m.mcc
LEFT JOIN kaiserver.[dbKAI].[dbo].[Account] ac ON crm.account_no = ac.account_no
AND ac.current_ind=1
AND and datepart(yyyy,ac.account_submit_dt) in ('2013', '2014')
LEFT JOIN [fdserver].fdms.[dbo].[tbl_reps] e1 ON e1.repcode=CRM.Sales_Rep_Cd
AND e1.market not like ('%TEST%')
and e1.payrollname is not null
and e1.region is not null
and e1.market is not null
LEFT JOIN [fdserver].fdms.[dbo].[tbl_reps] e2 ON e1.salesmanager = e2.repid
LEFT JOIN kaiserver.[dbKAI].[dbo].[BankAU_Hierarchy] BK ON CRM.referral_au = BK.AU_code
AND [Reporting_Interval_Id] = '201410'
LEFT JOIN kaiserver.[dbKAI].[dbo].[SoldVolumeDetail] sv ON crm.account_no = sv.merchantnumber
WHERE DATEPART(YYYY, CRM.Referral_dt) in ('2013', '2014')
AND ISNULL(crm.salesstatuscode,'') <> 'DUPL'
AND crm.lead_source not in ('Test Lead', 'Bank Lead Placeholder')
group by DATEPART(YYYY,Referral_dt), DATEPART(MM,Referral_dt), crm.Referral_State, crm.salesstatuscode, crm.lead_source, mp.mcc_desc,
mp.mcc_industry, sr.manager_name, sr.payrollname, sr.region,sr.market, sr.saleschannel, Bk.SuperRegion_Name, Bk.Region_Name ,Bk.Division_Name,
CASE
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2013' AND '4/14/2013' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2013' AND '7/14/2013' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2013' AND '9/30/2013' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2013' AND '12/31/2013' THEN 'Q4'
WHEN CAST(Referral_dt as date) BETWEEN '1/1/2014' AND '4/14/2014' THEN 'Q1'
WHEN CAST(Referral_dt as date) BETWEEN '4/15/2014' AND '7/14/2014' THEN 'Q2'
WHEN CAST(Referral_dt as date) BETWEEN '7/15/2014' AND '9/30/2014' THEN 'Q3'
WHEN CAST(Referral_dt as date) BETWEEN '10/1/2014' AND '12/31/2014' THEN 'Q4'
ELSE 'X' END
This code does exactly what I need it to do for the desired months. Basically provides Numerator and Denominator.
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-01-01' and '2013-01-31' THEN 1 ELSE 0 END) AS Total_Jan13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-01-01' and '2013-01-31' and [ind_ra_cfvmc_00-30] = 'YES' THEN 1 ELSE 0 END) AS RA_Jan13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-02-01' and '2013-02-28' THEN 1 ELSE 0 END) AS Total_Feb13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-02-01' and '2013-02-28' and [ind_ra_cfvmc_00-30] = 'YES' THEN 1 ELSE 0 END) AS RA_Feb13,
SUM(CASE WHEN smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date BETWEEN '2013-03-01' and '2013-03-31' THEN 1 ELSE 0 END) AS Total_Mar13,
It can get pretty tedious when you have multiple months...is there a more efficient way of performing this calculation?
THanks!
You could group them by the year and month in a sub-select and then manipulate that:
SELECT DATEPART(year, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date) AS TotalYear,
DATEPART(month, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date) AS TotalMonth,
COUNT(*) AS Total
FROM [table]
GROUP BY DATEPART(year, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date),
DATEPART(month, smsdss.c_cfv_pas_fct_pt_acct_vst_all.vst_end_date)
and that would give you the totals by month, without having to specify the months beforehand.