THIS Data pull needs help. The efficiency/performance sucks and I don't know enough about SQL to make it better. I'm in the middle of a project that required me to learn SQL pretty fast, but considering the time frame I'm looking at, I've come to YOU, the PROS.... Any ideas from the pros to make this for efficient?
SELECT
d.[Date] AS [Date],
LEFT(CONVERT(VARCHAR,d.[Date],112),6) AS [YearMo],
FORMAT(d.[Date],'MMMM') AS [Month],
YEAR(d.[Date]) AS [Year],
e.[MbrNo] AS [Member ID],
e.[Mkt_State] AS [Mkt State],
e.[Mkt] AS [Mkt Segment],
COALESCE(e.[Individual_Premium_Amt],0) AS [Individual Premium],
COALESCE(e.[Total_Premium_Amt],0) AS [Total Premium],
COALESCE(v.[Inpatient_Pd],0) AS [Inpatient Pd],
COALESCE(v.[Outpatient_Pd],0) AS [Outpatient Pd],
COALESCE(v.[Professional_Pd],0) AS [Professional Pd],
COALESCE(v.[Other_Pd],0) AS [Other Pd],
COALESCE(v.[Med_Pd],0) AS [Med Pd],
COALESCE(SUM(v.[Med_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date])),0) AS [Total Med Pd YTD],
COALESCE(v.[Med_Allowed],0) AS [Med Allowed],
COALESCE(v.[Rx_Pd],0) AS [Rx Pd],
COALESCE(SUM(v.[Rx_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date])),0) AS [Total RX Pd YTD],
COALESCE(v.[Rx_Allowed],0) AS [Rx Allowed],
COALESCE(v.[Med_RX_Pd],0) AS [Med Rx Pd],
COALESCE(SUM(v.[Med_Pd] + v.[Rx_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date])
ORDER BY e.[MbrNo],LEFT(CONVERT(VARCHAR,d.[Date],112),6) ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW),0) AS [RS Med Rx Pd],
COALESCE(SUM(v.[Med_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date]))
+ SUM(v.[Rx_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date])),0) AS [Total Pd YTD],
COALESCE(v.[Med_RX_Allowed],0) AS [Med Rx Allowed],
CASE
WHEN ((SUM(v.[Med_Pd] + v.[Rx_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date]))) > rr.[Recover_Threshold])
THEN ((SUM(v.[Med_Pd] + v.[Rx_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date])) - rr.[Recover_Threshold]))
ELSE 0
END AS [Recoverable Amt],
SUM(1.0) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date])) AS [MM (Yearly)],
CASE
WHEN ((SUM(v.[Med_Pd] + v.[Rx_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date]))) > rr.[Recover_Threshold])
THEN ((SUM(v.[Med_Pd] + v.[Rx_Pd]) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date])) - rr.[Recover_Threshold]))
/ SUM(1.0) OVER (PARTITION BY e.[MbrNo],YEAR(d.[Date]))
ELSE 0
END AS [Recoverable Amtv2],
COALESCE(rr.[Members],0) AS [Members],
COALESCE(rr.[MM],0) AS [MM],
COALESCE(rr.[Rx_Rebates],0) AS [Rx Rebates],
COALESCE(rr.[RA_PMPM],0) AS [RA PMPM],
COALESCE(rr.[RA_Payable],0) AS [RA Payable],
COALESCE(rr.[Pd_Threshold],0) AS [SR Pd Threshold],
COALESCE(rr.[Recover_Threshold],0) AS [SR Recover Threshold],
COALESCE(rr.[CF_Inpatient_PMPM],0) AS [CF IP PMPM],
COALESCE(rr.[CF_Outpatient_PMPM],0) AS [CF OP PMPM],
COALESCE(rr.[CF_Professional_PMPM],0) AS [CF PROF PMPM],
COALESCE(rr.[CF_RX_PMPM],0) AS [CF RX PMPM],
COALESCE(rr.[CF_Med_PMPM],0) AS [CF Med PMPM],
COALESCE(SUM(rr.[CF_RX_PMPM])+(rr.[CF_Med_PMPM]),0) AS [CF Med_Rx PMPM]
FROM -- Date Scaffold - Each month starting 20170101 to the current GETDATE() month
(SELECT
DATEADD(MONTH,number,'20190101') AS [Date],
EOMONTH(DATEADD(MONTH,number,'20190101')) AS [EOM Date]
FROM MASTER..[spt_values]
WHERE TYPE='P'
AND DATEADD(MONTH,number,'20190101') <= GETDATE()
) AS d
INNER JOIN -- Join Med enrollment for each month to the date scaffold, creating the membermonths format
(SELECT
e.*
FROM [SomeDB].[dbo].[sometable] AS e
WHERE [benefitType]=930700000
AND e.[LOB]='Commercial'
AND e.[Segment_Cancelled]<>'Yes'
AND e.[Mbr_Status]<>'Pending Binder Payment'
AND e.[MbrNo]<>0
) AS e
ON e.[Start_Date]<=d.[Date] AND e.[End_Date]>=d.[EOM Date]
LEFT JOIN
(SELECT
c.[YEARMO],
c.[MEMBERID],
SUM(CASE WHEN c.[UTILGRP]='INPATIENT' THEN c.[Pd] ELSE 0 END) AS [Inpatient_Pd],
SUM(CASE WHEN c.[UTILGRP]='OUTPATIENT' THEN c.[Pd] ELSE 0 END) AS [Outpatient_Pd],
SUM(CASE WHEN c.[UTILGRP]='PROFESSIONAL' THEN c.[Pd] ELSE 0 END) AS [Professional_Pd],
SUM(CASE WHEN [UTILGRP]='OTHER' THEN c.[Pd] ELSE 0 END) AS [Other_Pd],
SUM(CASE WHEN c.[CLAIMTYPE]='Med' THEN c.[Pd] ELSE 0 END) AS [Med_Pd],
SUM(CASE WHEN c.[CLAIMTYPE]='Med' THEN c.[ALLOWED] ELSE 0 END) AS [Med_Allowed],
SUM(CASE WHEN c.[CLAIMTYPE]='Pharmacy' THEN c.[Pd] ELSE 0 END) AS [Rx_Pd],
SUM(CASE WHEN c.[CLAIMTYPE]='Pharmacy' THEN c.[ALLOWED] ELSE 0 END) AS [Rx_ALlowed],
SUM(CASE WHEN c.[CLAIMTYPE]='Med' OR c.[CLAIMTYPE]='Pharmacy' THEN c.[Pd] ELSE 0 END) AS [Med_RX_Pd],
SUM(CASE WHEN c.[CLAIMTYPE]='Med' OR c.[CLAIMTYPE]='Pharmacy' THEN c.[ALLOWED] ELSE 0 END) AS [Med_RX_Allowed]
FROM [SomeDB].[dbo].[SomeTable] AS c
WHERE c.[MbrNo] <> 0
AND c.[CLAIMLINESTATUS] NOT IN ('D','V')
AND c.[LOB]='IND'
GROUP BY c.[YearMo],c.[MbrNo]
) AS v
ON e.[MbrNo]=v.[MbrNo] AND LEFT(CONVERT(VARCHAR,d.[Date],112),6)=v.[YearMo]
LEFT JOIN [SomeDB].[dbo].[SomeTable] AS rr
ON e.[Mkt_Segment]=rr.[Mkt_Segment] AND LEFT(CONVERT(VARCHAR,d.[Date],112),6)=rr.[YearMo]
GROUP BY d.[Date],e.[MbrNo],e.[Mkt_State],e.[Mkt_Segment],e.[Individual_Premium_Amt],e.[Total_Premium_Amt],
v.[Inpatient_Pd],v.[Outpatient_Pd],v.[Professional_Pd],v.[Other_Pd],v.[Med_Pd],v.[Med_Allowed],v.[Rx_Pd],v.[Rx_Allowed],v.[Med_RX_Pd],v.[Med_RX_Allowed],
rr.[Members],rr.[MM],rr.[Rx_Rebates],rr.[RA_PMPM],rr.[RA_Payable],rr.[Pd_Threshold],rr.[Recover_Threshold],rr.[CF_Inpatient_PMPM],rr.[CF_Outpatient_PMPM],rr.[CF_Professional_PMPM],rr.[CF_RX_PMPM],rr.[CF_Med_PMPM]
I would replace all the <> 0 statements (Which is typically not SARGable) with >0 statements which is Sargable.
Related
i trying to figure to convert sumtchtraffic and totalpayloadGb column in sitetable and sum data totalpayloadGb & sumtchtraffic where BTS_TYPE 2g, 3g and 4g in techtable
i tried like this, but i cant show totalpayloadgb & sumtchtraffic in column [SUM OF] ([sum of] is not in any table in my database)
select * from (select
sum(case when techtable.BTS_TYPE='2G' then sitetable.TotalPayloadGb else 0 end) as [Total 2G],
sum(case when techtable.BTS_TYPE='3G' then sitetable.TotalPayloadGb else 0 end) as [Total 3G],
sum (case when techtable.BTS_TYPE='4G'then sitetable.TotalPayloadGb else 0 end) as [Total 4G]
from sitetable
inner join techtable on sitetable.sitename = techtable.sitename) as t
I want show my data like this:
One way would be to total your results separately, using the same conditional aggregation you have started, and then UNION the results together. Since your first column doesn't exist anywhere else, you'll have to hard-code it into the queries.
SELECT
'TotalPayloadGb' AS SumOf,
sum(CASE WHEN t.BTS_TYPE = '2G' THEN s.TotalPayloadGb ELSE 0 END) AS [Total 2G],
sum(CASE WHEN t.BTS_TYPE = '3G' THEN s.TotalPayloadGb ELSE 0 END) AS [Total 3G],
sum(CASE WHEN t.BTS_TYPE = '4G' THEN s.TotalPayloadGb ELSE 0 END) AS [Total 4G]
FROM sitetable AS s
INNER JOIN techtable AS t
ON s.sitename = t.sitename
UNION
SELECT
'SumTCHTraffic' AS SumOf,
sum(CASE WHEN t.BTS_TYPE = '2G' THEN s.SumTCHTraffic ELSE 0 END) AS [Total 2G],
sum(CASE WHEN t.BTS_TYPE = '3G' THEN s.SumTCHTraffic ELSE 0 END) AS [Total 3G],
sum(CASE WHEN t.BTS_TYPE = '4G' THEN s.SumTCHTraffic ELSE 0 END) AS [Total 4G]
FROM sitetable AS s
INNER JOIN techtable AS t
ON s.sitename = t.sitename;
Depending on what you are trying to do, you could do like this:
SELECT tt.BTS_Type, sum(st.TotalPayloadDb)
FROM SiteTable st
INNER JOIN TechTable as tt on st.sitename = tt.sitename
This will give one row per BTS_Type value.
Heys guys, I asked yesterday about optimizing a query, and with some help I managed to get my query from taking 20 seconds to running instantly.
This was the question (and it contains an example of the underlying table) -> Is there any way to improve the efficiency of this SQL query and make it run faster?
The problem was solved by being smarter about aggregates and group by. However, I still have some trouble with group by. I want to post another query that is against the exact same table and see if anyone sees anyway to improve the efficiency of this query.
So originally, this query was a whole mess. I tried to apply a similar GROUP BY technique that fixed the first query to this query as well but it didn't really pan out.
Here is what I ended up with after I cleaned everything up:
BEGIN
DECLARE #LocalCompanyCode VARCHAR(5)
SET #LocalCompanyCode = '09'
DECLARE #LocalDivisionCode VARCHAR(5)
SET #LocalDivisionCode = '001'
DECLARE #LocalCustomerBaseFromDate DATETIME
SET #LocalCustomerBaseFromDate = '1/1/2018'
DECLARE #LocalCustomerBaseToDate DATETIME
SET #LocalCustomerBaseToDate = '9/1/2019'
DECLARE #LocalRecurringBaseFromDate DATETIME
SET #LocalRecurringBaseFromDate = '1/1/2017'
DECLARE #LocalLifetimeBaseFromDate DATETIME
SET #LocalLifetimeBaseFromDate = '1/1/2016'
SELECT
*
FROM (
SELECT
Email
,Date_Created
,BrandNewCustomer
,RecurringCustomer
,ReactivatedCustomer
,TotalOrders
,TotalCustomerValue
,TotalQuantity
,TotalOrdersNewBase
,TotalCustomerValueNewBase
,TotalQuantityNewBase
,TotalOrdersRecurringBase
,TotalCustomerValueRecurringBase
,TotalQuantityRecurringBase
,TotalOrdersLifetimeBase
,TotalCustomerValueLifetimeBase
,TotalQuantityLifetimeBase
,SUM(TotalCustomerValueNewBase) Over () BaseCustomersTotal
,SUM(TotalCustomerValueRecurringBase) Over () RecurringCustomersTotal
,SUM(TotalCustomerValueLifetimeBase) Over () LifetimeCustomersTotal
,SUM(TotalCustomerValue) Over () AllCustomersTotal
,(dense_rank() over (order by (case when Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) then Email end) asc) +
dense_rank() over (order by (case when Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) then Email end) desc) - 1
) as TotalCustomersOverCustomerBase
,(dense_rank() over (order by (case when Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate then Email end) asc) +
dense_rank() over (order by (case when Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate then Email end) desc) - 1
) as TotalCustomersOverRecurringBase
,(dense_rank() over (order by (case when Date_Created BETWEEN #LocalLifetimeBaseFromDate and #LocalRecurringBaseFromDate then Email end) asc) +
dense_rank() over (order by (case when Date_Created BETWEEN #LocalLifetimeBaseFromDate and #LocalRecurringBaseFromDate then Email end) desc) - 1
) as TotalCustomersOverLifetimeBase
,(DENSE_RANK() over (order by Email asc)
+DENSE_RANK() over ( order by Email desc)
- 1) as TotalCustomersOverBase
,SUM( CASE WHEN (BrandNewCustomer + RecurringCustomer + ReactivatedCustomer) = 1 THEN 1 ELSE 0 END) over () KeptCustomers
,SUM( CASE WHEN (BrandNewCustomer + RecurringCustomer + ReactivatedCustomer) = 0 THEN 1 ELSE 0 END) over () LostCustomers
FROM (
SELECT
T.Email
,MAX(T.Date_Created) Date_Created
,COUNT(*) TotalOrders
,SUM(T.Order_Sell_price) TotalCustomerValue
,SUM(T.Quantity_Ordered) TotalQuantity
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) THEN 1 ELSE 0 END) TotalOrdersNewBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) THEN Order_Sell_price ELSE 0 END) TotalCustomerValueNewBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) THEN Quantity_Ordered ELSE 0 END) TotalQuantityNewBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate THEN 1 ELSE 0 END) TotalOrdersRecurringBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate THEN Order_Sell_price ELSE 0 END) TotalCustomerValueRecurringBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate THEN Quantity_Ordered ELSE 0 END) TotalQuantityRecurringBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalLifetimeBaseFromDate and #LocalRecurringBaseFromDate THEN 1 ELSE 0 END) TotalOrdersLifetimeBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalLifetimeBaseFromDate and #LocalRecurringBaseFromDate THEN Order_Sell_price ELSE 0 END) TotalCustomerValueLifetimeBase
,SUM(CASE WHEN T.Date_Created BETWEEN #LocalLifetimeBaseFromDate and #LocalRecurringBaseFromDate THEN Quantity_Ordered ELSE 0 END) TotalQuantityLifetimeBase
,CASE WHEN
( ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) THEN 1 ELSE 0 END),0) >= 1
AND ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate THEN 1 ELSE 0 END),0) = 0
AND ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalLifetimeBaseFromDate and #LocalRecurringBaseFromDate THEN Quantity_Ordered ELSE 0 END),0) = 0)
THEN 1 ELSE 0 END BrandNewCustomer
,CASE WHEN
( ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) THEN 1 ELSE 0 END),0) >= 1
AND ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate THEN 1 ELSE 0 END),0) >= 1)
THEN 1 ELSE 0 END RecurringCustomer
,CASE WHEN
( ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalCustomerBaseFromDate and DATEADD(dayofyear, 1, #LocalCustomerBaseToDate) THEN 1 ELSE 0 END),0) >= 1
AND ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalRecurringBaseFromDate and #LocalCustomerBaseFromDate THEN 1 ELSE 0 END),0) = 0
AND ISNULL(SUM(CASE WHEN T.Date_Created BETWEEN #LocalLifetimeBaseFromDate and #LocalRecurringBaseFromDate THEN Quantity_Ordered ELSE 0 END),0) >= 1)
THEN 1 ELSE 0 END ReactivatedCustomer
FROM (
SELECT
F.Email
,F.Coal_Date Date_Created
,Month(F.Coal_Date) Month
,Year(F.Coal_Date) Year
,F.Customer_Purchase_Order_Number
,F.Order_Status
,Row_Number() over (Partition by Email order by Coal_Date asc) OrderCount
,F.Order_Sell_price
,F.Order_Quantity_Ordered Quantity_Ordered
FROM
FinalEcomTable F
WHERE
1=1
AND (F.Company_Code = #LocalCompanyCode OR #LocalCompanyCode IS NULL)
AND (F.Division_Code = #LocalDivisionCode OR #LocalDivisionCode IS NULL)
AND F.Coal_Date BETWEEN #LocalLifetimeBaseFromDate AND DATEADD(dayofyear, 1, #LocalCustomerBaseToDate)
AND F.Order_Status <> 'CANCELLED'
AND F.Odet_Line_Number = 1
) T
GROUP BY T.Email
) TT
) TTT
WHERE (BrandNewCustomer + RecurringCustomer + ReactivatedCustomer) = 1
ORDER BY email DESC
END
And here is the full execution plan:
https://www.brentozar.com/pastetheplan/?id=SkDyXPfDH
Those 4 dense_rank lines by themselves are almost doubling the run time. I realize now that its usually always these types of lines that do that.
I'll try to explain a bit about my thinking behind the query. So it is based on the same table as my first query. In reality, I am dealing with lots of data across three different linked servers, so I decided to create one master table that I would update every day and instead of calling to the linked servers and causing everything to run super slow, I would just call to that table.
So the most inner query takes each customer email, and then by each email, gets each order and what order number this is (first, second, etc). Is it a problem that I am doing Over () for my Row_Number aggregate? I would want to Group By Email but then how would I get each actual order number? Because if I group be email, then I have to do something like Max() of each order number, but I want the actual order number. Is there any way to do this?
Then the next outer query takes this data and actually groups by email. Over this group by I calculate totals over certain date ranges. The idea for this report is that there are three date ranges. New, which is what the actual report is based on and that range is something like the past 3 months. I look at all the customers in the past three months and then I see if they have any purchases in the recurring date range (a year before the three months) or the lifetime date range. Then I determine whether they are new customer or a recurring customer (or reactivated) by just putting a 1 on which type of customer it is.
Then my final outer query takes that data and calculates overall totals like Total value of all my recurring customers or total kept vs lost customers and so on. And like I mentioned before the dense_ranks really trip me up here. I feel like if I could add a Group By to this last query, I can solve a lot of my performance problems, but I can't seem to figure out how to integrate it.
Currently, this query runs about 10-15 seconds and I feel it could be instant. I tried creating the index the execution plan suggested but it didn't do anything.
--I am trying to simply add one subquery to take the total sales of each salesperson in relation to their quotes. I am at a loss and hopefully someone can help.
select sp.FIRST_NAME + ' ' + sp.LAST_NAME,
sum(case when sq.SAL_QUOTE_STATUS_ID = '1' then 1 else 0 end) as [Created],
sum(case when sq.SAL_QUOTE_STATUS_ID = '4' then 1 else 0 end) as [Ordered],
sum(case when sq.SAL_QUOTE_STATUS_ID = '3' then 1 else 0 end) as [Rejected],
sum(sq.AMOUNT_INCLUDING_TAX) as [Amount],
sum(sq.COST) as [Cost],
sum(sq.AMOUNT_INCLUDING_TAX - sq.COST) as [Profit],
round(100 * (case when sum(sq.AMOUNT_INCLUDING_TAX) > 0 then
(sum(sq.AMOUNT_INCLUDING_TAX) -
sum(sq.COST)) / sum(sq.AMOUNT_INCLUDING_TAX) else 0 end), 3) as [GP%],
(Select sum(so.amount_including_tax)
from SAL_SALES_ORDER so
where so.SALESPERSON_ID = sp.SALESPERSON_ID) as [YTD Sales]
from SAL_SALES_QUOTE sq
inner join CRM_SALESPERSON sp on sp.SALESPERSON_ID = sq.SALESPERSON_ID
where sq.CREATED_DATE > '01-01-2018'
group by sp.FIRST_NAME + ' ' + sp.LAST_NAME
I took your subquery out of the select, made it into a result set to join on , and then pulled the sum from there.
select sp.FIRST_NAME + ' ' + sp.LAST_NAME,
sum(case when sq.SAL_QUOTE_STATUS_ID = '1' then 1 else 0 end) as [Created],
sum(case when sq.SAL_QUOTE_STATUS_ID = '4' then 1 else 0 end) as [Ordered],
sum(case when sq.SAL_QUOTE_STATUS_ID = '3' then 1 else 0 end) as [Rejected],
sum(sq.AMOUNT_INCLUDING_TAX) as [Amount],
sum(sq.COST) as [Cost],
sum(sq.AMOUNT_INCLUDING_TAX - sq.COST) as [Profit],
round(100 * (case when sum(sq.AMOUNT_INCLUDING_TAX) > 0 then
(sum(sq.AMOUNT_INCLUDING_TAX) -
sum(sq.COST)) / sum(sq.AMOUNT_INCLUDING_TAX) else 0 end), 3) as [GP%],
sum([x.ytd_sales]) AS YTD_Sales
from SAL_SALES_QUOTE sq
inner join CRM_SALESPERSON sp on sp.SALESPERSON_ID = sq.SALESPERSON_ID
inner join (Select so.salesperson_id, sum(so.amount_including_tax) AS [YTD Sales]
from SAL_SALES_ORDER so
group by so.salesperson_id) x
ON x.salesperson_id = sp.salesperson_id
where sq.CREATED_DATE > '01-01-2018'
group by sp.FIRST_NAME + ' ' + sp.LAST_NAME
So I have the following 2 columns
,sum(case when Owner_Faculty_Full_Desc = 'Business and Law Faculty' then 1 else 0 end) [Business Current Year]
,sum(case when Owner_Faculty_Full_Desc = 'Business and Law Faculty' AND Apps.Reporting_Year = (Apps.Reporting_Year - 1) then 1 else 0 end) [Business Previous Year]
Lets say that Apps.ReportingYear is 2011, how to I get the second column to sum all values in 2010? I thought my statement would work but it doesn't seem to be.
Here is the entire query
WITH Equiv_day AS (
SELECT Date_Key, Sem1_Equivalent_Day
FROM [AUTDataWarehouse].[dbo].[Dim_Date]
WHERE Full_Date = CONVERT(DATE, GETDATE())
),
Date_list AS (
SELECT dt.Date_Key, dt.Calendar_Year
FROM [AUTDataWarehouse].[dbo].[Dim_Date] AS dt
INNER JOIN Equiv_day AS ed
ON (ed.Sem1_Equivalent_Day - 1) = dt.Sem1_Equivalent_Day
AND dt.Calendar_Year IN (YEAR(GETDATE()), YEAR(GETDATE())-1, YEAR(GETDATE()) - 2, YEAR(GETDATE()) - 3, YEAR(GETDATE()) - 4, YEAR(GETDATE()) - 5)
),
PYTD_Outcome_by_Application AS (
SELECT
se.Reporting_Year,
f.Student_Demographics_Key,
f.Application_Code,
Outcome_Row = Max(f.Application_Row_Num)
FROM AUTDataWarehouse.dbo.Fact_Admission as f
INNER JOIN AUTDataWarehouse.dbo.Dim_Intake as it
ON it.Intake_Key = f.Intake_Key
AND it.Prog_Intake_Type_Desc = 'Intake'
INNER JOIN AUTDataWarehouse.dbo.Dim_Semester as se
ON se.Semester_Key = f.Semester_Key
INNER JOIN AUTDataWarehouse.dbo.Dim_Campus as cp
ON cp.Campus_Key = f.Campus_Key
INNER JOIN Date_list as dates
ON dates.Calendar_Year = se.Reporting_Year
WHERE f.Last_Change_Date_Key < dates.Date_Key
GROUP BY
se.Reporting_Year,
f.Student_Demographics_Key,
f.Application_Code
),
Applications_Count AS (
SELECT
p.Owner_Faculty_Full_Desc,
p.Programme_Full_Desc,
et.Enrolment_Type_Key,
se.Reporting_Year,
sd.Last_Secondary_School_Name [LastSchoolName],
pr.Programme_Key,
Campus = CASE WHEN cp.Campus_Name IN ('South','South Dist') THEN 'South' ELSE 'City / North Shore' END,
se.Semester_Desc,
f.Student_Demographics_Key,
Applicants = COUNT(DISTINCT f.Student_Demographics_Key)
FROM AUTDataWarehouse.dbo.Fact_Admission as f
INNER JOIN AUTDataWarehouse.dbo.Dim_Student_Demographics as sd ON sd.Student_Demographics_Key = f.Student_Demographics_Key
INNER JOIN AUTDataWarehouse.dbo.Dim_Programme as P on P.Programme_Key = f.Programme_Key
INNER JOIN AUTDataWarehouse.dbo.Dim_Intake as it
ON it.Intake_Key = f.Intake_Key
AND it.Prog_Intake_Type_Desc = 'Intake'
INNER JOIN AUTDataWarehouse.dbo.Dim_Enrolment_Type as et
ON et.Enrolment_Type_Key = f.Enrolment_Type_Key
INNER JOIN AUTDataWarehouse.dbo.Dim_Programme as pr
ON pr.Programme_Key = f.Programme_Key
INNER JOIN AUTDataWarehouse.dbo.Dim_Campus as cp
ON cp.Campus_Key = f.Campus_Key
INNER JOIN AUTDataWarehouse.dbo.Dim_Semester as se
ON se.Semester_Key = f.Semester_Key
INNER JOIN Date_list as dates
ON dates.Calendar_Year = se.Reporting_Year
INNER JOIN PYTD_Outcome_by_Application AS pytd
ON pytd.Application_Code = f.Application_Code
AND pytd.Student_Demographics_Key = f.Student_Demographics_Key
AND pytd.Outcome_Row = f.Application_Row_Num
and pytd.Reporting_Year = se.Reporting_Year
AND pytd.Application_Code IS NOT NULL
GROUP BY
sd.Last_Secondary_School_Name,
p.Owner_Faculty_Full_Desc,
p.Programme_Full_Desc,
et.Enrolment_Type_Key,
se.Reporting_Year,
pr.Programme_Key,
CASE WHEN cp.Campus_Name IN ('South','South Dist') THEN 'South' ELSE 'City / North Shore' END,
se.Semester_Desc,
f.Student_Demographics_Key
)
SELECT
CAST(EP.Educational_Provider_Key as varchar(10)) as 'Education Key'
,[LastSchoolName]
,Owner_Faculty_Full_Desc
,Programme_Full_Desc
,Apps.Reporting_Year
,cast(cast(Apps.Reporting_Year as varchar(255)) + '0101' as datetime) as [YearTime]
,sum(case when Owner_Faculty_Full_Desc = 'Business and Law Faculty' then 1 else 0 end) [Business and Law Current Year]
,sum(case when Owner_Faculty_Full_Desc = 'Business and Law Faculty' AND (Apps.Reporting_Year = Apps.Reporting_Year - 1) then 1 else 0 end) [Business and Law Previous Year]
,sum(case when Owner_Faculty_Full_Desc = 'Culture and Society Faculty' then 1 else 0 end) [Culture and Society Current Year]
,sum(case when Owner_Faculty_Full_Desc = 'Culture and Society Faculty' AND Apps.Reporting_Year = 2014 then 1 else 0 end) [Culture and Society Previous Year]
,sum(case when Owner_Faculty_Full_Desc = 'Design & Creative Technologies Faculty'then 1 else 0 end) [Design & Creative TechnologiesCurrent Year]
,sum(case when Owner_Faculty_Full_Desc = 'Design & Creative Technologies Faculty' AND Apps.Reporting_Year = (Apps.Reporting_Year - 1) then 1 else 0 end) [Design & Creative Technologies Previous Year]
,sum(case when Owner_Faculty_Full_Desc = 'Health & Environmental Sciences Faculty'then 1 else 0 end) [Health & Environmental Sciences Current Year]
,sum(case when Owner_Faculty_Full_Desc = 'Health & Environmental Sciences Faculty' AND Apps.Reporting_Year = (Apps.Reporting_Year - 1) then 1 else 0 end) [Health & Environmental Sciences Previous Year]
,sum(case when Owner_Faculty_Full_Desc = 'Te Ara Poutama' then 1 else 0 end) [Te Ara Poutama Current Year]
,sum(case when Owner_Faculty_Full_Desc = 'Te Ara Poutama' AND Apps.Reporting_Year = (Apps.Reporting_Year - 1) then 1 else 0 end) [Te Ara Poutama Previous Year]
,sum(apps.Applicants) [Total Applicants]
FROM Applications_Count as Apps
inner join AUTDataWarehouse.dbo.Dim_Educational_Provider as EP on EP.Provider_Name = [LastSchoolName]
GROUP BY Apps.Reporting_Year, [LastSchoolName], EP.Educational_Provider_Key,Owner_Faculty_Full_Desc
, Programme_Full_Desc
ORDER BY Apps.Reporting_Year, [Total Applicants] DESC
So basically for each programme I want a column for total applicants for the ReportingYear then total applicants for the Reporting Year - 1
Thanks!
Probably easiest to calculate the years separately, then self-join to get the value for the previous year. This is the basic logic you would use, although obviously you will need to make it more complex when you adapt it to the long query above:
;with CTE as (select ReportingYear
, sum(case when [condition] then 1 else 0 end) as ValueCurrYear
from MyTables
group by ReportingYear)
Select a.*, b.ValueCurrYear as ValuePreviousYear
from CTE a
left join CTE b
on a.ReportingYear = b.ReportingYear + 1
I am using this code to get a sum of prices but there will also be negative numbers in this column that i will not want to be part of the equation at this point. What's the best way to filter those numebers out?
ISNULL (SUM(CAST(JC11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY JC11.JOB_NUMB),
SUM(CAST(OE11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY OE11.ORD_NUMB)) AS REVENUE
SELECT DISTINCT
CONVERT(CHAR(10), DATEADD(d, CU10.DAT_CREATED +5843, 0), 1)AS 'DATE ENTERED'
,CU10.CUST_NAME
,CU10.INDUSTRY_CODE
,JC17.IND_DESC
,COUNT(JC10.JOB_NUMB) OVER(PARTITION BY JC10.JOB_NUMB) AS JOB_TOTAL
,COUNT(OE10.ORD_NUMB) OVER(PARTITION BY OE10.ORD_NUMB) AS ORDER_TOTAL
,ISNULL(JC10.JOB_NUMB,
OE10.ORD_NUMB) AS 'JOB/ORDER'
,ISNULL ((SELECT TOP 1 JC10.DATE_SHIPPED FROM JC10 WHERE JC10.BILLTO_NUMB = CU10.BILLTO_NUMB ORDER BY JC10.DATE_SHIPPED DESC),
(SELECT TOP 1 OE10.DATE_SHIPPED FROM OE10 WHERE OE10.BILLTO_NUMB = CU10.BILLTO_NUMB ORDER BY OE10.DATE_SHIPPED DESC)) AS DATE_SHIPPED
,ISNULL (SUM(CAST(JC11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY JC11.JOB_NUMB),
SUM(CAST(OE11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY OE11.ORD_NUMB)) AS REVENUE
,(SELECT DISTINCT SUM(CAST(JC21.ACTUAL_DLR AS MONEY)) OVER(PARTITION BY JC21.JOB_NUMB) FROM JC21 WHERE JC21.JOB_NUMB = OE10.ORD_NUMB OR JC21.JOB_NUMB = JC10.JOB_NUMB AND (CAST(JC21.ACTUAL_HRS AS MONEY) > 0.00 )) AS LABOR_COSTS
,(SELECT DISTINCT SUM(CAST(JC20.TOT_COSTS AS MONEY)) OVER(PARTITION BY JC20.JOB_NUMB) FROM JC20 WHERE JC20.JOB_NUMB = OE10.ORD_NUMB OR JC20.JOB_NUMB = JC10.JOB_NUMB )
+ ISNULL((SELECT DISTINCT SUM(CAST(JC21.ACTUAL_DLR AS MONEY)) OVER(PARTITION BY JC21.JOB_NUMB) FROM JC21 WHERE JC21.JOB_NUMB = OE10.ORD_NUMB OR JC21.JOB_NUMB = JC10.JOB_NUMB AND (CAST(JC21.ACTUAL_HRS AS MONEY) > 0.00 )),0) AS TOTAL_COSTS
,(ISNULL (SUM(CAST(JC11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY JC11.JOB_NUMB),
SUM(CAST(OE11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY OE11.ORD_NUMB))) - (SELECT DISTINCT SUM(CAST(JC20.TOT_COSTS AS MONEY)) OVER(PARTITION BY JC20.JOB_NUMB) FROM JC20 WHERE JC20.JOB_NUMB = OE10.ORD_NUMB OR JC20.JOB_NUMB = JC10.JOB_NUMB )
- ISNULL((SELECT DISTINCT SUM(CAST(JC21.ACTUAL_DLR AS MONEY)) OVER(PARTITION BY JC21.JOB_NUMB) FROM JC21 WHERE JC21.JOB_NUMB = OE10.ORD_NUMB OR JC21.JOB_NUMB = JC10.JOB_NUMB AND (CAST(JC21.ACTUAL_HRS AS MONEY) > 0.00 )),0) AS PROFIT
--,(SELECT SUM(CAST (JC11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY JC11.JOB_NUMB) FROM JC11 WHERE CAST(JC11.SALE_PRICE1 AS MONEY) < 0.00)
--,(SELECT TOP 1 JC10.DATE_SHIPPED FROM JC10 WHERE JC10.BILLTO_NUMB = CU10.BILLTO_NUMB ORDER BY JC10.DATE_SHIPPED DESC) AS LAST_JOB_SHIPPED_DATE
--,(SELECT TOP 1 OE10.DATE_SHIPPED FROM OE10 WHERE OE10.BILLTO_NUMB = CU10.BILLTO_NUMB ORDER BY OE10.DATE_SHIPPED DESC) AS LAST_ORDER_SHIPPED_DATE
--,SUM(CAST(JC11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY JC11.JOB_NUMB) AS JC_REVENUE
--,SUM(CAST(OE11.SALE_PRICE1 AS MONEY)) OVER(PARTITION BY OE11.ORD_NUMB) AS OE_REVENUE
--,JC10.JOB_NUMB
--,OE10.ORD_NUMB
FROM CU10
JOIN JC17 AS JC17 ON JC17.CODE = CU10.INDUSTRY_CODE
LEFT OUTER JOIN JC10 AS JC10 ON JC10.BILLTO_NUMB = CU10.BILLTO_NUMB
LEFT OUTER JOIN OE10 AS OE10 ON OE10.BILLTO_NUMB = CU10.BILLTO_NUMB
LEFT OUTER JOIN JC11 AS JC11 ON JC11.JOB_NUMB = JC10.JOB_NUMB
LEFT OUTER JOIN OE11 AS OE11 ON OE11.ORD_NUMB = OE10.ORD_NUMB
WHERE
CONVERT(CHAR(10), DATEADD(d, CU10.DAT_CREATED +5843, 0), 112) > 20150101
AND (JC10.JOB_SHIPPED_FLAG = 'Y' OR OE10.ORD_SHIPPED_FLAG = 'Y')
You make make use of a CASE statement for this.
ISNULL (SUM(CASE WHEN JC11.SALE_PRICE1 >= 0 then CAST(JC11.SALE_PRICE1 AS MONEY) else 0.00 end) OVER(PARTITION BY JC11.JOB_NUMB),
SUM(CASE WHEN OE11.SALE_PRICE1 >= 0 then CAST(OE11.SALE_PRICE1 AS MONEY) else 0.00 end) OVER(PARTITION BY OE11.ORD_NUMB)) AS REVENUE
I'm not sure what the rest of the query is doing. But something that's like what others have done, but including the negative portion is:
ISNULL(
SUM(CASE WHEN CAST(JC11.SALE_PRICE1 AS MONEY) >=0 THEN CAST(JC11.SALE_PRICE1 AS MONEY) ELSE 0.0 END) OVER(PARTITION BY JC11.JOB_NUMB),
SUM(CASE WHEN CAST(OE11.SALE_PRICE1 AS MONEY) >=0 THEN CAST(OE11.SALE_PRICE1 AS MONEY) ELSE 0.0 END) OVER(PARTITION BY OE11.ORD_NUMB)
) AS POSITIVE_REVENUE,
ISNULL(
SUM(CASE WHEN CAST(JC11.SALE_PRICE1 AS MONEY) <=0 THEN CAST(JC11.SALE_PRICE1 AS MONEY) ELSE 0.0 END) OVER(PARTITION BY JC11.JOB_NUMB),
SUM(CASE WHEN CAST(OE11.SALE_PRICE1 AS MONEY) <=0 THEN CAST(OE11.SALE_PRICE1 AS MONEY) ELSE 0.0 END) OVER(PARTITION BY OE11.ORD_NUMB)
) AS NEGATIVE_REVENUE
Without the rest of the query (from, where conditions, etc.) it will be pretty difficult to formulate a real query.