Can switch statements cause a 'Query is too Complex' error in MS Access 365? - sql

As background, we are currently using Lotus Approach as our job schedule database. Out of fear that one day it'll cease working with newer versions of Windows, I've been searching for an alternative that isn't terribly dissimilar from Approach. One of the features in Approach that has been wonderful is that calculated fields are stored in the front end and has full access to all tables in the database, as well as other calculated fields without having to link them to forms, reports, or each other. I have yet to find a program that handles calculated fields in a similar manner, so I've moved to using queries in Access to beginning building these calculated fields (around 200 formulas).
That said, I have 4 tables and 3 queries, but I'm hitting a wall with one of the queries. In the query that's giving me the error, I think I've determined the problem has to do with 1 switch statement (AUDIT_JTD_EARNED_REV) as there are 3 other formulas that rely on this calculation and if I delete one of these (not all of them), then the query will run.
I have not used Access before in any meaningful way, so if there is a better way of doing it, then I'm all ears. Below are the 3 queries I'm using and the error is occurring in the Audit Calc query.
Audit Calc
SELECT Book.job_id,
(
Book.jtd_ti_cost - Book.audit_jtd_ti_cost + Book.jtd_eq_credit + Book.sdp_profit ) AS AUDIT_FCST_PROFIT_ADJ,
Book.book_jtd_cost - audit_fcst_profit_adj + ICalc.ic_audit_jtd_profit_adj
AS
AUDIT_JTD_COST,
Switch(Book.stat_cd = 'C', Book.jtd_gross_bill + Book.accrued_billing,
( Book.stat_cd = 'I'
AND
audit_jtd_cost + audit_fcst_profit >
Book.book_contract_amt * audit_pct_cmpl )
OR (
Book.stat_cd = 'A'
AND Book.job_type <> '2'
AND audit_pct_cmpl >= 0.2 ), Round(Book.book_contract_amt * audit_pct_cmpl, 2),
Book.stat_cd = 'A'
AND Book.job_type = '1'
AND audit_pct_cmpl < 0.2, audit_jtd_cost, true,
audit_jtd_cost + audit_fcst_profit)
AS AUDIT_JTD_EARNED_REV,
Book.book_contract_amt - audit_fcst_profit
AS AUDIT_FCST_COST,
Switch(Book.book_contract_amt < 1, 1, Book.job_type = 2,
Book.jtd_gross_bill - Book.accrued_billing / Book.book_contract_amt, true,
audit_jtd_cost / audit_fcst_cost)
AS AUDIT_PCT_CMPL,
Nz(Book.fcst_job_profit)
+ audit_fcst_profit_adj
+ Nz(ICalc.ic_audit_fcst_profit)
AS AUDIT_FCST_PROFIT,
Round(audit_jtd_earned_rev - Nz(Book.prior_adt_rev), 2)
AS AUDIT_YTD_EARNED_REV,
audit_jtd_cost + audit_addl_loss - Nz(Book.prior_adt_cost)
AS AUDIT_YTD_COST,
audit_ytd_earned_rev - audit_ytd_cost
AS AUDIT_YTD_EARNED_PROFIT,
Switch(Book.prime_job_id IS NULL
OR ( Nz(Book.fcst_job_profit, 0) - Nz(ICBook.fcst_job_profit, 0) ) > 0
OR Book.stat_cd <> 'A'
OR
( Book.book_contract_amt - audit_fcst_cost ) >= 0, 0, true,
audit_fcst_profit - audit_jtd_cost + audit_jtd_earned_rev)
AS AUDIT_ADDL_LOSS,
Iif(Book.stat_cd <> "a", 0, audit_fcst_cost - audit_jtd_cost)
AS
AUDIT_FCST_COST_TO_CMPL,
audit_fcst_profit / Iif(Book.job_type = 2,
Book.book_contract_amt, audit_fcst_cost)
AS AUDIT_PROFIT_PCT,
audit_jtd_earned_rev - audit_jtd_cost + audit_addl_loss
AS
AUDIT_JTD_EARNED_PROFIT,
audit_jtd_earned_rev - Book.jtd_gross_bill - Book.accrued_billing + Nz(Book.jtd_ret_amt) AS AUDIT_OVER_UNDER_BILLING
FROM ([book calc] AS Book
LEFT JOIN [book calc] AS ICBook
ON Book.job_id = ICBook.prime_job_id)
LEFT JOIN [interco calc] AS ICalc
ON Book.job_id = ICalc.prime_job_id;
Interco Calc
SELECT [book calc].prime_job_id
AS PRIME_JOB_ID,
[book calc].job_id
AS SUB_JOB_ID,
[book calc].jtd_ti_cost - [book calc].audit_jtd_ti_cost +
[book calc].jtd_eq_credit + [book calc].sdp_profit
AS IC_AUDIT_FCST_PROFIT_ADJ,
[book calc].fcst_job_profit
+ ic_audit_fcst_profit_adj
AS IC_AUDIT_FCST_PROFIT,
Round([book calc].jtd_mat_cost
+ [book calc].jtd_sub_cost
+ [book calc].jtd_oth_cost
+ [book calc].jtd_gl_cost
+ [book calc].jtd_eq_cost
+ [book calc].jtd_labor_cost
+ [book calc].accrued_cost
+ Nz([book calc].prior_adt_ti)
+ [book calc].audit_ytd_ti_cost - Nz([book calc].prior_eq_credit) -
[book calc].ytd_eq_credit + [book calc].jtd_sdp_cost -
[book calc].sdp_profit, 2)
AS IC_AUDIT_JTD_COST,
ic_audit_jtd_cost - ( [book calc].jtd_gross_bill
+ [book calc].accrued_billing )
AS IC_AUDIT_JTD_PROFIT_ADJ,
Iif([book calc].book_contract_amt < 1, 1,
Iif([book calc].job_type = 2, ( [book calc].gross_bill
+ [book calc].accrued_billing ) /
[book calc].book_contract_amt, ic_audit_jtd_cost / ic_audit_fcst_cost)) AS IC_AUDIT_PCT_CMPL,
[book calc].book_contract_amt - ic_audit_fcst_profit
AS IC_AUDIT_FCST_COST
FROM [book calc]
WHERE ( [book calc].prime_job_id ) IS NOT NULL;
And finally Book Calc
SELECT fsjob.*,
eq_aed.eq_aed_prem
AS EQ_AED_PREM,
eq_aed.eq_aed_chrg
AS EQ_AED_CHRG,
Nz(fsjob.gross_bill)
+ Nz(fsjob.prior_gross_bill)
+ Nz(fsjob.prior_accr_bill)
AS JTD_GROSS_BILL,
Round(Nz(fsjob.sc_cost) + Nz(fsjob.prior_sc_cost), 2)
AS JTD_SUB_COST,
Nz(fsjob.labor_cost)
+ Nz(fsjob.prior_labor_cost)
AS JTD_LABOR_COST,
Nz(fsjob.oth_cost)
+ Nz(fsjob.prior_oth_cost)
AS JTD_OTH_COST,
Nz(fsjob.mat_cost)
+ Nz(fsjob.prior_mat_cost)
AS JTD_MAT_COST,
Nz(fsjob.eq_cost) + Nz(fsjob.prior_eq_cost)
AS JTD_EQ_COST,
Nz(fsjob.gl_cost) + Nz(fsjob.prior_gl_cost)
AS JTD_GL_COST,
Nz(fsjob.ti_cost) + Nz(fsjob.prior_ti_cost)
AS JTD_TI_COST,
Iif(( fsjob.sdp_cd = 'SDP'
AND fsjob.stat_cd = 'I' )
OR ( fsjob.sdp_cd = 'SDP'
AND jtd_gross_bill > 0
AND fsjob.stat_cd = 'A'
AND jtd_sub_cost > 0 ), Round(variable.sdp_pct *
Nz(fsjob.fcst_sc_cost), 2), 0)
AS
JTD_SDP_COST,
Switch(fsjob.stat_cd = 'I', Nz(fsjob.contract_amt, 0) - jtd_gross_bill, true, Nz(fsjob.accr_bill_adj, 0))
AS ACCRUED_BILLING,
Switch(fsjob.stat_cd = 'C', jtd_gross_bill + accrued_billing, true, Nz(fsjob.contract_amt, 0))
AS BOOK_CONTRACT_AMT,
Iif(fsjob.stat_cd = 'I', Round(
book_contract_amt - Nz(fsjob.fcst_job_profit)
- jtd_sub_cost + jtd_labor_cost + jtd_oth_cost + jtd_mat_cost + jtd_eq_cost + jtd_gl_cost + jtd_ti_cost + jtd_sdp_cost, 2), Nz(fsjob.accr_cost_adj))
AS ACCRUED_COST,
Round(jtd_sub_cost + jtd_labor_cost + jtd_oth_cost
+ jtd_mat_cost + jtd_eq_cost + jtd_gl_cost
+ jtd_ti_cost + jtd_sdp_cost + accrued_cost, 2)
AS BOOK_JTD_COST,
Round(book_contract_amt - Nz(fsjob.fcst_job_profit), 2)
AS BOOK_FCST_COST,
Iif(fsjob.stat_cd = 'C'
OR
book_contract_amt < 1, 1,
Iif(fsjob.job_type = 2, ( accrued_billing + jtd_gross_bill ) / book_contract_amt, book_jtd_cost / book_fcst_cost))
AS BOOK_PCT_CMPL,
Iif(fsjob.stat_cd <> 'A', Round(jtd_gross_bill + accrued_billing, 2),
Iif(fsjob.job_type = 2,
Iif(( book_jtd_cost + Nz(fsjob.fcst_job_profit) ) < (
book_contract_amt * book_pct_cmpl ),
Nz(fsjob.fcst_job_profit) + book_jtd_cost, Round(
book_pct_cmpl * book_contract_amt, 2)),
Iif(Nz(fsjob.fcst_job_profit) < 0, Nz(fsjob.fcst_job_profit) + book_jtd_cost, Iif(book_pct_cmpl < 0.195, book_jtd_cost,
Round(
book_pct_cmpl * book_contract_amt, 2)))))
AS
BOOK_JTD_EARNED_REV,
( book_jtd_earned_rev - book_jtd_cost )
AS BOOK_JTD_PROFIT,
Iif(fsjob.stat_cd = 'C', book_jtd_profit, Nz(fsjob.fcst_job_profit))
AS
BOOK_FCST_PROFIT,
( book_contract_amt - book_fcst_profit - book_jtd_cost )
AS BOOK_COST_TO_CMPL,
( Nz(fsjob.prior_bk_rev) - Nz(fsjob.prior_bk_cost) )
AS BOOK_PRIOR_PROFIT,
Round(book_jtd_cost - Nz(fsjob.prior_bk_cost), 2)
AS BOOK_YTD_COST,
Round(book_jtd_earned_rev - Nz(fsjob.prior_bk_rev), 2)
AS BOOK_YTD_EARNED_REV,
( book_ytd_earned_rev - book_ytd_cost )
AS BOOK_YTD_PROFIT,
Iif(fsjob.stat_cd = 'C', 0, Nz(fsjob.fcst_ye_labor) - jtd_labor_cost)
AS
LABOR_COST_TO_CMPL,
Round(jtd_gross_bill + accrued_billing - book_jtd_earned_rev, 2)
AS
BOOK_EXCESS_BILLING,
Round(Iif(( fsjob.sdp_cd = 'SDP'
AND fsjob.stat_cd = 'I' )
OR ( fsjob.sdp_cd = 'SDP'
AND Nz(jtd_gross_bill) > 0
AND fsjob.stat_cd = 'A'
AND
Nz(jtd_sub_cost) > 0 ), variable.sdp_pct * Nz(fsjob.fcst_sc_cost), 0), 2)
AS
SDP_REV,
Round(Iif(fsjob.sdp_cd IS NOT NULL
AND
fsjob.stat_cd <> 'C',
Iif(Nz(fsjob.fcst_sc_cost) > Nz(jtd_sub_cost),
Nz(fsjob.fcst_sc_cost) * variable.sdp_pct, Nz(jtd_sub_cost) * variable.sdp_pct), 0), 2)
AS FCST_SDP_REV,
Round(Iif(fsjob.sdp_cd IS NOT NULL
AND
fsjob.stat_cd <> 'C',
Nz(fsjob.sc_cost) / variable.ytd_sdp_sub_cost * variable.ytd_sdp_exp, 0), 2)
AS SDP_EXP,
( Nz(sdp.prior_cost) + Nz(sdp.curr_cost)
+ Nz(sdp.curr_ap) - Nz(sdp.prior_ap) + sdp_exp )
AS JTD_SDP_EXP,
Iif(fsjob.sdp_cd <> 'SDP'
OR fsjob.stat_cd = 'C', 0, Round(Nz(fsjob.fcst_sc_cost) - jtd_sub_cost, 2))
AS SUB_COST_TO_CMPL,
fcst_sdp_rev - jtd_sdp_exp - fcst_sdp_addl_reserve_amt
AS FCST_SDP_PROFIT,
sdp_rev - jtd_sdp_exp
AS SDP_PROFIT,
Iif(book_pct_cmpl < 0.195, Round(( fcst_sdp_rev - jtd_sdp_exp ) * 0.5, 2), 0)
AS
FCST_SDP_ADDL_RESERVE_AMT,
Iif(Nz(fsjob.fcst_job_profit) < 0, fcst_sdp_profit - Nz(fsjob.prior_sdp_credit), Iif(book_pct_cmpl < 0.195, 0,
Round(
book_pct_cmpl * fcst_sdp_profit - Nz(fsjob.prior_sdp_credit), 2)))
AS
YTD_SDP_CREDIT,
Iif(fsjob.stat_cd = 'C', fcst_sdp_profit,
Iif(Nz(fsjob.fcst_job_profit) < 0, fcst_sdp_profit - Nz(fsjob.prior_sdp_credit),
Iif(Nz(fsjob.fcst_ye_pct_cmpl) < 0.195, 0,
Round(Nz(fsjob.fcst_ye_pct_cmpl) * fcst_sdp_profit - Nz(fsjob.prior_sdp_credit), 2)))) AS FCST_SDP_CREDIT,
sdp_profit - ytd_sdp_credit - Nz(fsjob.prior_sdp_credit)
AS YTD_SDP_RESERVE_AMT,
ytd_sdp_credit + Nz(fsjob.prior_sdp_credit)
AS JTD_SDP_CREDIT,
Round(Nz(eq_aed.eq_aed_chrg) / variable.ytd_eq_rev * variable.ytd_eq_profit, 2)
AS YTD_EQ_CREDIT,
ytd_eq_credit + Nz(fsjob.prior_eq_credit)
AS JTD_EQ_CREDIT,
Round(fsjob.ti_pct * Nz(fsjob.fcst_labor_cost), 2)
AS FCST_TI_COST,
audit_ytd_ti_cost + Nz(fsjob.prior_adt_ti)
AS AUDIT_JTD_TI_COST,
Switch(fsjob.ti_pct = 0.1, Nz(fsjob.ti_cost), true,
Round((jtd_labor_cost-Nz(fsjob.prior_labor_cost))*variable.actual_ti_pct, 2)
+ Nz(fsjob.wc_cost, 0))
AS AUDIT_YTD_TI_COST
FROM ((fsjob
LEFT JOIN variable
ON fsjob.var_ctrl_num = variable.var_ctrl_num)
LEFT JOIN eq_aed
ON fsjob.job_id = eq_aed.job_id)
LEFT JOIN sdp
ON fsjob.job_id = sdp.job_id;
The deepest nested IIF in all of these is only 3 deep and the most complex Switch statement only has 4 options. And the fields used in these statements are not overly complex, either. I've been fighting to simplify this for about a week and don't believe I can make it any more concise.
Thanks in advance.

Related

Formula to Divide Total of Columns and Format Result Not Valid

I have the following SQL code below that is returning an error message stating that the AvgPYs column is not valid. This is also impacting my Auth column. Is there an issue with my formula? Any help is appreciated.
SELECT [tblCeiling].[Proj Code], [tblCeiling].[Act Code], [tblCeiling].[Cost Ctr], [tblCeiling].[Date], [tblCeiling].[Ref2], [tblCeiling].[Analyst], [tblCeiling].[Type], [tblCeiling].[B or O], [tblCeiling].[Jul], [tblCeiling].[Aug],
[tblCeiling].[Sep], [tblCeiling].[Oct], [tblCeiling].[Nov], [tblCeiling].[Dec], [tblCeiling].[Jan], [tblCeiling].[Feb], [tblCeiling].[Mar], [tblCeiling].[Apr], [tblCeiling].[May], [tblCeiling].[Jun], [tblCeiling].[Perm], [tblCeiling].[Temp], [tblCeiling].[LimitedTerm],
[tblCeiling].[LTDate], [tblCeiling].[Sal_Rate], [tblCeiling].[New], [Perm] + [Temp] + [LimitedTerm] AS Monthly, Format(([tblCeiling].[Jul] + [tblCeiling].[Aug] + [tblCeiling].[Sep] + [tblCeiling].[Oct] + [tblCeiling].[Nov] + [tblCeiling].[Dec] + [tblCeiling].[Jan] +
[tblCeiling].[Feb] + [tblCeiling].[Mar] + [tblCeiling].[Apr] + [tblCeiling].[May] + [tblCeiling].[Jun]) / 12, '0.0####') AS AvgPYs,
((([Sal_Rate] * [AvgPYs]) * 1000) / 1000) AS Auth, [Dollar Adj] + [Auth] AS Budget, [tblCeiling].[Import], [tblCeiling].[Dollar Adj], [tblCeiling].[OngoingOrOneTime], [tblCeiling].[OneTimeEndingDate]
FROM (SELECT DISTINCT *
FROM [tblactcode]) AS [tblactcode] RIGHT JOIN
(SELECT DISTINCT *
FROM [tblCeiling]) AS [tblCeiling] ON [tblactcode].[Act Code] = [tblCeiling].[Act Code]
WHERE ((([tblCeiling].[Jul]) = iif([jul] IS NULL, 0, [jul])) AND (([tblCeiling].[Aug]) = iif([aug] IS NULL, 0, [aug])) AND (([tblCeiling].[Sep]) = iif([sep] IS NULL, 0, [sep])) AND (([tblCeiling].[Oct]) = iif([oct] IS NULL, 0, [oct])) AND (([tblCeiling].[Nov]) = iif([nov] IS NULL,
0, [nov])) AND (([tblCeiling].[Dec]) = iif([dec] IS NULL, 0, [dec])) AND (([tblCeiling].[Jan]) = iif([jan] IS NULL, 0, [jan])) AND (([tblCeiling].[Feb]) = iif([feb] IS NULL, 0, [feb])) AND (([tblCeiling].[Mar]) = iif([mar] IS NULL, 0, [mar])) AND (([tblCeiling].[Apr])
= iif([apr] IS NULL, 0, [apr])) AND (([tblCeiling].[May]) = iif([may] IS NULL, 0, [may])) AND (([tblCeiling].[Jun]) = iif([jun] IS NULL, 0, [jun])) AND (([tblCeiling].[Import]) = 0))
ORDER BY [tblCeiling].[Proj Code], [tblCeiling].[Cost Ctr], [tblCeiling].[Date]
Here is the specific line I'm referring to:
Format(([tblCeiling].[Jul] + [tblCeiling].[Aug] + [tblCeiling].[Sep] + [tblCeiling].[Oct] + [tblCeiling].[Nov] + [tblCeiling].[Dec] + [tblCeiling].[Jan] +
[tblCeiling].[Feb] + [tblCeiling].[Mar] + [tblCeiling].[Apr] + [tblCeiling].[May] + [tblCeiling].[Jun]) / 12, '0.0####') AS AvgPYs,
The specific issue you have run into is attempting to use a calculation in the same scope you are calculating it - which isn't possible. You can only access a calculated value in an outer query.
Or a neat solution is to use CROSS APPLY which allows you to reuse a calculation as follows. In general this is done as:
select -- existing columns before AvgPYs
, AvgPYs
-- , some formula which depends on AvgPYs
from (
-- existing query
) C -- C is an acceptable short alias for Ceiling
cross apply (
values (formula)
) X (AvgPYs)
In your case I think the following is correct:
SELECT C.[Proj Code], C.[Act Code], C.[Cost Ctr], C.[Date], C.[Ref2], C.[Analyst], C.[Type], C.[B or O], C.[Jul], C.[Aug]
, C.[Sep], C.[Oct], C.[Nov], C.[Dec], C.[Jan], C.[Feb], C.[Mar], C.[Apr], C.[May], C.[Jun], C.[Perm], C.[Temp], C.[LimitedTerm]
, C.[LTDate], C.[Sal_Rate], C.[New], [Perm] + [Temp] + [LimitedTerm] AS Monthly
, X.AvgPYs
, Y.Auth
, [Dollar Adj] + Y.Auth AS Budget, C.[Import], C.[Dollar Adj], C.[OngoingOrOneTime], C.[OneTimeEndingDate]
FROM (
SELECT DISTINCT *
FROM [tblactcode]
) AS AC
RIGHT JOIN (
SELECT DISTINCT *
FROM [tblCeiling]
) AS C ON AC.[Act Code] = C.[Act Code]
CROSS APPLY (
VALUES (Format((C.[Jul] + C.[Aug] + C.[Sep] + C.[Oct] + C.[Nov] + C.[Dec] + C.[Jan] +
C.[Feb] + C.[Mar] + C.[Apr] + C.[May] + C.[Jun]) / 12, '0.0####'))
) AS X (AvgPYs)
CROSS APPLY (
VALUES (((([Sal_Rate] * X.AvgPYs) * 1000) / 1000))
) Y (Auth)
WHERE (((C.[Jul]) = iif([jul] IS NULL, 0, [jul])) AND ((C.[Aug]) = iif([aug] IS NULL, 0, [aug])) AND ((C.[Sep]) = iif([sep] IS NULL, 0, [sep])) AND ((C.[Oct]) = iif([oct] IS NULL, 0, [oct])) AND ((C.[Nov]) = iif([nov] IS NULL,
0, [nov])) AND ((C.[Dec]) = iif([dec] IS NULL, 0, [dec])) AND ((C.[Jan]) = iif([jan] IS NULL, 0, [jan])) AND ((C.[Feb]) = iif([feb] IS NULL, 0, [feb])) AND ((C.[Mar]) = iif([mar] IS NULL, 0, [mar])) AND ((C.[Apr])
= iif([apr] IS NULL, 0, [apr])) AND ((C.[May]) = iif([may] IS NULL, 0, [may])) AND ((C.[Jun]) = iif([jun] IS NULL, 0, [jun])) AND ((C.[Import]) = 0)
)
ORDER BY C.[Proj Code], C.[Cost Ctr], C.[Date];
Note: A key purpose of a table alias is to have a short reference to the table. See how much easier it is to read with shorter aliases.

Converting Oracle Query to Snowflake

Please need some help to convert the below oracle code to Snowflake. When I m trying this, facing invalid identifier, rownum,
SELECT Customer_Id
,Release_type
,Customer_Name
,XYZ_Product_Name
,XYZ_Product_Salesforce_Number
,XYZ_Product_Code
,XYZ_Product_Type
,Brand_Family
,Qty_Purchased
,qty_u2dt
,sbc_Term_Start_Date
,sbc_Term_End_Date
,Months_Sold
,Months_Used
,Remaining_Months
,round(decode(Months_Sold, 0, 0, (Months_Used / Months_Sold) * 100), 2) AS Term_used_perc
,round(Actual_monthly_Usage, 2) AS Actual_monthly_Usage
,round((Actual_monthly_Usage * Remaining_Months) + qty_u2dt, 2) AS projected_usage
,round(decode(Qty_Purchased, 0, 0, (((Actual_monthly_Usage * Remaining_Months) + qty_u2dt) / Qty_Purchased) * 100), 2) AS projected_usage_perc
,round((((Actual_monthly_Usage * Remaining_Months) + qty_u2dt) - Qty_Purchased), 2) AS projected_over_under_usage
,CASE
WHEN round(decode(Qty_Purchased, 0, 0, (((Actual_monthly_Usage * Remaining_Months) + qty_u2dt) / Qty_Purchased) * 100), 2) = 100
AND Qty_Purchased = qty_u2dt
THEN 'Resell'
WHEN round(decode(Qty_Purchased, 0, 0, (((Actual_monthly_Usage * Remaining_Months) + qty_u2dt) / Qty_Purchased) * 100), 2) < 100
THEN 'Churn'
WHEN round(decode(Qty_Purchased, 0, 0, (((Actual_monthly_Usage * Remaining_Months) + qty_u2dt) / Qty_Purchased) * 100), 2) > 100
THEN 'Upsell'
WHEN round(decode(Qty_Purchased, 0, 0, (((Actual_monthly_Usage * Remaining_Months) + qty_u2dt) / Qty_Purchased) * 100), 2) = 100
AND Qty_Purchased = (round((Actual_monthly_Usage * Remaining_Months) + qty_u2dt))
THEN 'On Track'
ELSE 'Unknown'
END Projected_Indicator
,Timeline
,Contr_End_Date
,Salesforce_Account_Number
,Salesforce_csa_Id
,Salesforce_Contact
,Product_Family_Description
,Product_Family_Code
,Product_Brand_Description
,Product_Brand_Code
,Product_Category_Description
,Product_Category_Code
,Product_Name
,Product_Code
,product_type
,s_2_CUSTOMER_OWNER_NID
,G_Customer_Number
,G_Customer_Name
,G_Customer_Address
,G_Customer_City
,G_Customer_Country
,G_Customer_Phone
,G_Customer_State_Prov
,G_Customer_Zip_Code
,G_Customer_SFDC_NID
,G_Customer_SFDC_NID_Link
,s_2_Customer_Number
,s_2_Customer_Name
,s_2_Customer_Address
,s_2_Customer_City
,s_2_Customer_Country
,s_2_Customer_Phone
,s_2_Customer_State_Prov
,s_2_Customer_Zip_Code
,s_2_Customer_Health_Status
,s_2_Customer_SFDC_NID
,s_2_Customer_SFDC_NID_Link
,s_2_Customer_XYZ_NID
,s_2_Customer_XYZ_NID_Link
,s_2_Customer_Sales_Owner
,s_2_Customer_CSM
,s_2_Customer_CSM_Manager
,s_2_Customer_Sales_Manager
,s_2_customer_sales_team
,s_2_Customer_PSM
,s_2_Customer_PSM_Manager
,sbc_number
,sbc_status
,subscriptiontype
,sbc_start_date
,sbc_end_date
,sbc_termination_date
,sbc_SFDC_NID
,sbc_SFDC_NID_Link
,istestaccount
,child_sub_name
,parent_sub_name
,requiredbyid
,Parent_PRODUCTID
,parent_productname
,Initial_recurrinng_term
,Recurrinng_reolover_term
,renewal_date
,rate_set_uom
,Unit_of_Measure
,Contract_Number
,Contract_SFDC_NID
,Contract_SFDC_NID_Link
,Contract_Start_Date
,Contract_End_Date
FROM (
SELECT Customer_Id
,Release_type
,Customer_Name
--,Contract_Number
,XYZ_Product_Name
,XYZ_Product_Salesforce_Number
,XYZ_Product_Code
,XYZ_Product_Type
,Brand_Family
,Qty_Purchased
,qty_u2dt
,sbc_Term_Start_Date
,sbc_Term_End_Date
,round(months_between(sbc_Term_End_Date, sbc_Term_Start_Date), 2) AS Months_Sold
,round(months_between(current_date, sbc_Term_Start_Date), 2) AS Months_Used
,(round(months_between(sbc_Term_End_Date, sbc_Term_Start_Date), 2)) - (round(months_between(current_date, sbc_Term_Start_Date), 2)) AS Remaining_Months
,decode(months_between(current_date, sbc_Term_Start_Date), 0, 0, ((qty_u2dt / months_between(current_date, sbc_Term_Start_Date)))) AS Actual_monthly_Usage
,CASE
WHEN sbc_Term_End_Date < current_date
THEN 'Past'
WHEN sbc_Term_Start_Date > current_date
THEN 'Future'
ELSE 'Present'
END Timeline
,Contr_End_Date
,Salesforce_Account_Number
,Salesforce_csa_Id
,Salesforce_Contact
,Product_Family_Description
,Product_Family_Code
,Product_Brand_Description
,Product_Brand_Code
,Product_Category_Description
,Product_Category_Code
,Product_Name
,Product_Code
,product_type
,s_2_CUSTOMER_OWNER_NID
,G_Customer_Number
,G_Customer_Name
,G_Customer_Address
,G_Customer_City
,G_Customer_Country
,G_Customer_Phone
,G_Customer_State_Prov
,G_Customer_Zip_Code
,G_Customer_SFDC_NID
,G_Customer_SFDC_NID_Link
,s_2_Customer_Number
,s_2_Customer_Name
,s_2_Customer_Address
,s_2_Customer_City
,s_2_Customer_Country
,s_2_Customer_Phone
,s_2_Customer_State_Prov
,s_2_Customer_Zip_Code
,s_2_Customer_Health_Status
,s_2_Customer_SFDC_NID
,s_2_Customer_SFDC_NID_Link
,s_2_Customer_XYZ_NID
,s_2_Customer_XYZ_NID_Link
,s_2_Customer_Sales_Owner
,s_2_Customer_CSM
,s_2_Customer_CSM_Manager
,s_2_Customer_Sales_Manager
,s_2_customer_sales_team
,s_2_Customer_PSM
,s_2_Customer_PSM_Manager
,sbc_number
,sbc_status
,subscriptiontype
,sbc_start_date
,sbc_end_date
,sbc_termination_date
,sbc_SFDC_NID
,sbc_SFDC_NID_Link
,istestaccount
,child_sub_name
,parent_sub_name
,requiredbyid
,Parent_PRODUCTID
,parent_productname
,Initial_recurrinng_term
,Recurrinng_reolover_term
,renewal_date
,rate_set_uom
,Unit_of_Measure
,Contract_Number
,Contract_SFDC_NID
,Contract_SFDC_NID_Link
,Contract_Start_Date
,Contract_End_Date
FROM (
SELECT DISTINCT cust.Id AS Customer_Id
,sub.rtpname AS Release_type
,org.Name AS Customer_Name
,prod.Name AS XYZ_Product_Name
,prod.SalesforceId AS XYZ_Product_Salesforce_Number
,prod.Code AS XYZ_Product_Code
,prod.Type AS XYZ_Product_Type
,pb.Name AS Brand_Family
,cntr.CURRENCYISOCODE AS currency_code
,nvl((
SELECT *
FROM (
SELECT to_char(cliterm.Quantity)
FROM XYZ_ContractLineItemTerm cliterm
WHERE cliterm.ContractLineItem_id = cli.Id
AND (
cliterm.EndDate IS NULL
OR cliterm.EndDate > add_months(current_date, - 3)
)
AND cliterm.PriceRuleItem_id IS NULL
ORDER BY cli.id DESC
)
WHERE rownum = 1
), cli.Quantity) AS Qty_Purchased
,nvl((
SELECT *
FROM (
SELECT cliterm.UsedQuantity
FROM XYZ_ContractLineItemTerm cliterm
WHERE cliterm.ContractLineItem_id = cli.Id
AND (
cliterm.EndDate IS NULL
OR cliterm.EndDate > add_months(current_date, - 3)
)
AND cliterm.PriceRuleItem_id IS NULL
ORDER BY cli.id DESC
)
WHERE rownum = 1
), cli.UsedQuantity) AS qty_u2dt
,nvl((
SELECT *
FROM (
SELECT cliterm.StartDate
FROM XYZ_ContractLineItemTerm cliterm
WHERE cliterm.ContractLineItem_id = cli.Id
AND (
cliterm.EndDate IS NULL
OR cliterm.EndDate > add_months(current_date, - 3)
)
AND cliterm.PriceRuleItem_id IS NULL
ORDER BY cli.id DESC
)
WHERE rownum = 1
), cli.StartDate) AS sbc_Term_Start_Date
,nvl((
SELECT *
FROM (
SELECT cliterm.EndDate
FROM XYZ_ContractLineItemTerm cliterm
WHERE cliterm.ContractLineItem_id = cli.Id
AND (
cliterm.EndDate IS NULL
OR cliterm.EndDate > add_months(current_date, - 3)
)
AND cliterm.PriceRuleItem_id IS NULL
ORDER BY id DESC
)
WHERE rownum = 1
), cli.EndDate) AS sbc_Term_End_Date
,nvl(to_char(cli.EndDate), (
CASE
WHEN (
cli.StartDate IS NOT NULL
AND con.InitialTerm > 0
)
THEN 'Auto Renewal'
ELSE ''
END
)) AS Contr_End_Date
,cust.SalesforceAccountNumber AS Salesforce_Account_Number
,cust.SalesforceId AS Salesforce_csa_Id
,'s12345' || con.SalesforceId || '/view' AS Salesforce_Contact
,prod_fam.product_family_code AS product_family_code
,prd.Product_Family__c AS Product_Family_Description
,prd.Brand_Code__c AS Product_Brand_Code
,prd.Product_Brand__c AS Product_Brand_Description
,prd.Category_Code__c AS Product_Category_Code
,prd.Product_Category__c AS Product_Category_Description
,prd.name AS Product_Name
,prd.productcode AS Product_Code
,prd.PRODUCT_TYPE__C AS product_type
,dasruler.id AS s_2_CUSTOMER_OWNER_NID
,rupa.global_ultimate_d_u_n_s_number AS G_Customer_Number
,rupa.name AS G_Customer_Name
,rupa.billingstreet AS G_Customer_Address
,rupa.billingcity AS G_Customer_City
,rupa.billingcountry AS G_Customer_Country
,rupa.phone AS G_Customer_Phone
,rupa.billingstate AS G_Customer_State_Prov
,rupa.billingpostalcode AS G_Customer_Zip_Code
,rupa.id AS G_Customer_SFDC_NID
,'12345'|| rupa.id || '/view' AS G_Customer_SFDC_NID_Link
,csa.csa__c AS s_2_Customer_Number
,csa.name AS s_2_Customer_Name
,csa.account_address__c AS s_2_Customer_Address
,csa.account_city__c AS s_2_Customer_City
,csa.account_country__c AS s_2_Customer_Country
,csa.phone AS s_2_Customer_Phone
,csa.account_state_province__c AS s_2_Customer_State_Prov
,csa.account_zip_code__c AS s_2_Customer_Zip_Code
,csa.id AS s_2_Customer_SFDC_NID
,'12345' || csa.id || '/view' AS s_2_Customer_SFDC_NID_Link
,csa.client_health_status__c s_2_Customer_Health_Status
,cust.id AS s_2_Customer_XYZ_NID
,'q12345' || cust.id || '/view' AS s_2_Customer_XYZ_NID_Link
,nvl(dasruler.firstname || ' ' || dasruler.lastname, 'UNKNOWN') AS s_2_Customer_Sales_Owner
,nvl(csacsm.csm, 'UNKNOWN') AS s_2_Customer_CSM
,nvl(csm_mgr.NAME, 'NAVL') AS s_2_Customer_CSM_Manager
,nvl(csasalesmanager.firstname || ' ' || csasalesmanager.lastname, 'UNKNOWN') AS s_2_Customer_Sales_Manager
,nvl(csasalesmanager.USER_SEGMENT__C, 'UNKNOWN') AS s_2_customer_sales_team
,nvl(csapsm.psm, 'NAVL') AS s_2_Customer_PSM
,nvl(psm_mgr.name, 'NAVL') AS s_2_Customer_PSM_Manager
,sub.name AS sbc_number
,sub.STATUS__C AS sbc_status
,sub.sbqq__subscriptiontype__c AS subscriptiontype
,nvl(sub.sbqq__subscriptionstartdate__c, sub.sbqq__startdate__c) AS sbc_start_date
,sub.SBQQ__ENDDATE__C AS sbc_end_date
,sub.sbqq__terminateddate__c AS sbc_termination_date
,sub.annual_recurring_total__c AS annual_recurring_total__c
,sub.one_time_total__c AS one_time_total__c
,sub.currencyisocode AS Localcurrency
,sub.id AS sbc_SFDC_NID
,'z12345' || sub.id || '/view' AS sbc_SFDC_NID_Link
,sub.name AS child_sub_name
,sub.RECURRING_INITIAL_TERM__C AS Initial_recurrinng_term
,sub.RECURRING_ROLLOVER_TERM__C AS Recurrinng_reolover_term
,sub.RENEWAL_DATE__C AS renewal_date
,pasub.name AS parent_sub_name
,sub.sbqq__requiredbyid__c AS requiredbyid
,pasub.SBQQ__PRODUCTID__C AS Parent_PRODUCTID
,pasub.SBQQ__PRODUCTNAME__C AS Parent_Productname
,csa.is_test_account__c AS istestaccount
,prd.rate_set_uom__C AS rate_set_uom
,PRD.Quantity_unit_of_measure__C AS Unit_of_Measure
,cntr.CONTRACTNUMBER AS Contract_Number
,cntr.id AS Contract_SFDC_NID
,'c123456'|| cntr.id || '/view' AS Contract_SFDC_NID_Link
,cntr.startdate AS Contract_Start_Date
,cntr.enddate AS Contract_End_Date
,cntr.annual_recurring_total__c AS Contract_annual_recurring_amt
,cntr.one_time_total__c AS Contract_one_time_total
,cntr.initial_term_total__c AS First_year_contract_value
FROM XYZ_ContractLineItem cli
INNER JOIN XYZ_Contract con ON cli.Contract_id = con.Id
INNER JOIN XYZ_Customer cust ON con.Customer_id = cust.Id
INNER JOIN XYZ_Organization org ON org.Customer_id = cust.Id
INNER JOIN XYZ_Product prod ON cli.Product_id = prod.Id
INNER JOIN XYZ_ProductBrand pb ON prod.ProductBrand_id = pb.Id
LEFT JOIN sfacc csa ON cust.SalesforceAccountNumber = csa.csa__c
LEFT JOIN sfacc rupa ON csa.parentid = rupa.id
LEFT JOIN sf_SBQQ__sbc__C sub ON sub.id = cli.salesforceid
LEFT JOIN SF_SBQQ__sbc__C pasub ON pasub.id = sub.sbqq__requiredbyid__c
LEFT JOIN contractor cntr ON cntr.contractnumber = con.ContractNumber
LEFT JOIN sfu dasruler ON csa.ownerid = dasruler.id
LEFT JOIN sfu dassalesmgr ON dasruler.managerid = dassalesmgr.id
LEFT JOIN (
SELECT f.accountid
,g.managerid
,max(g.NAME) CSM
,max(g.id) CSMID
FROM sfatm f
JOIN sfu g ON f.userid = g.id
WHERE f.teammemberrole = 'AGM'
GROUP BY f.accountid
,g.managerid
) dasagm ON dasagm.accountid = csa.id
LEFT JOIN sfu csm_mgr ON dasagm.managerid = csm_mgr.id
LEFT JOIN (
SELECT f.accountid
,g.managerid
,max(g.NAME) PSM
,max(g.id) CSMID
FROM sfatm f
JOIN sfu g ON f.userid = g.id
WHERE f.teammemberrole = 'SDM'
GROUP BY f.accountid
,g.managerid
) dassdm ON dassdm.accountid = csa.id
LEFT JOIN sfu psm_mgr ON dassdm.managerid = psm_mgr.id
LEFT JOIN SFP prd ON prod.Code = prd.productcode
LEFT JOIN IPFam prod_fam ON prod_fam.product_family_desc = prd.Product_Family__c
WHERE cli.RateEffectiveStatus = 'A'
AND cli.STATUS = 'A'
AND cli.Active = 1
AND con.STATUS IN ('A')
AND CUST.STATUS = 'active'
AND prod.type <> 'KING'
AND csa.itac = 0
)
WHERE Qty_Purchased <> 0
);
Snowflake doesn't have a ROWNUM keyword as Oracle does.
If you want to use that functionality, you can generate an equivalent using the window function, row_number(). This would typically be done by inserting that window function into the bottom level of your query.

What is the Big-O of this nested loop?

int z=1;
for(int i=0;i*i<n;i++){
z*=3;
for(int j=0;j<z;j++){
// Some code
}
}
Answer is O(3^n).
Is it correct? How to figure out time complexity of nested loop?
outer loop: i goes from 1 to sqrt(n);
inner loop: j,z goes up to 3^(sqrt(n));
"some code" will run 1 + 3 + 3^2 + ... + 3^(sqrt(n)) times
let sum = 1 + 3 + 3^2 + ... + 3^(sqrt(n))
sum - 3*sum = 1 - 3(sqrt(n) + 1)
sum = 1 - 3(sqrt(n) + 1) / (1-3) = 2( 3^(sqrt(n)+1) - 1 )
2( 3^(sqrt(n)+1) - 1 ) << O( 3^sqrt(n) )
O(3^sqrt(n)) is more accurate
You could approach the problem using Sigma notation this way:

Groovy - ORA-00933: SQL command not properly ended [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
Why am I getting this error from my code? This runs in SQuirreL but I get the "ORA-00933: SQL command not properly ended" in Groovy. Arrrrrrgh! Please help me, you knowledge is greatly appreciated and coveted. My error occurs when I write the output to file. How do I select the correct table becore writing?
It is the ending line(s) that produce the error:
file.write("")
db.eachRow(sql) {
file.append(it.MOPID + "\t" + it.TYPE + "\n")
}
import groovy.sql.Sql
def db = Sql.newInstance(
'jdbc:oracle:thin:#10.10.47.193:1521:ORCL',
'reporter', 'r3p0rt3r', 'oracle.jdbc.pool.OracleDataSource')
def sql = """
DROP TABLE TEMPXMOP24
CREATE TABLE TEMPXMOP24
(
MOPID VARCHAR2(12),
TYPE VARCHAR2(200),
MOPSTART DATE,
MOPAPPROVEDTIME DATE,
TIME_DIF VARCHAR2(45),
TIME_ORDER NUMBER(10),
FIXED_MOP VARCHAR2(12),
MOP_HR VARCHAR2(2)
);
INSERT INTO TEMPXMOP24 (MOPID,TYPE,MOPSTART,MOPAPPROVEDTIME,TIME_DIF,TIME_ORDER,FIXED_MOP,MOP_HR)
SELECT MOPACTIVITY.MOPID,
MOPACTIVITY.MOPSERVICEIMPACTED "TYPE",
MOPACTIVITY.MOPSTART,
MOPACTIVITY.MOPAPPROVEDTIME,
ROUND(MOPACTIVITY.MOPSTART - MOPACTIVITY.MOPAPPROVEDTIME,2)||' days' "TIME_DIF",
ROUND(MOPACTIVITY.MOPSTART - MOPACTIVITY.MOPAPPROVEDTIME,0) "TIME_ORDER",
(CASE
WHEN SUBSTR(MOPACTIVITY.MOPID, 7, 2) = '24' THEN SUBSTR(MOPACTIVITY.MOPID, 1, 6)||'00'||SUBSTR(MOPACTIVITY.MOPID, 9, 4)
ELSE MOPACTIVITY.MOPID
END ) FIXED_MOP,
(CASE
WHEN SUBSTR(MOPACTIVITY.MOPID, 7, 2) = '24' THEN SUBSTR(MOPACTIVITY.MOPID, 7, 2)
ELSE SUBSTR(MOPACTIVITY.MOPID, 7, 2)
END ) MOP_HR
FROM MOPUSER.MOPACTIVITY
WHERE MOPACTIVITY.MOPSTART - MOPACTIVITY.MOPAPPROVEDTIME BETWEEN 0 and 14;
SELECT * FROM TEMPXMOP24
WHERE TRUNC(TO_DATE(FIXED_MOP, 'MMDDYYHH24MISS'))
BETWEEN TRUNC(SYSDATE-90) AND TRUNC(SYSDATE)
ORDER BY "TIME_ORDER"
def date = new Date()
def dts = date.format("yyyy-MM-dd-HH-mm-ss")
File file = new File('C:/Documents and Settings/e0148840/Desktop/' + dts + ' Caries 14 Day and Out.xls')
file.write("")
db.eachRow(sql) {
file.append(it.MOPID + "\t" + it.TYPE + "\n")
}
Here ya go!
import groovy.sql.Sql
def db = Sql.newInstance(
'jdbc:oracle:thin:#1X.XX.XXX.XXX:1521:ORCL',
'XXXXXX', 'XXXXXX', 'oracle.jdbc.pool.OracleDataSource')
def sql = """
SELECT * FROM
(SELECT MOPACTIVITY.MOPID,
MOPACTIVITY.MOPSERVICEIMPACTED "TYPE",
MOPACTIVITY.MOPSTART,
MOPACTIVITY.MOPAPPROVEDTIME,
ROUND(MOPACTIVITY.MOPSTART - MOPACTIVITY.MOPAPPROVEDTIME,2)||' days' "TIME_DIF",
ROUND(MOPACTIVITY.MOPSTART - MOPACTIVITY.MOPAPPROVEDTIME,0) "TIME_ORDER",
(CASE
WHEN SUBSTR(MOPACTIVITY.MOPID, 7, 2) = '24' THEN SUBSTR(MOPACTIVITY.MOPID, 1, 6)||'00'||SUBSTR(MOPACTIVITY.MOPID, 9, 4)
ELSE MOPACTIVITY.MOPID
END ) FIXED_MOP,
(CASE
WHEN SUBSTR(MOPACTIVITY.MOPID, 7, 2) = '24' THEN SUBSTR(MOPACTIVITY.MOPID, 7, 2)
ELSE SUBSTR(MOPACTIVITY.MOPID, 7, 2)
END ) MOP_HR
FROM MOPUSER.MOPACTIVITY
WHERE MOPACTIVITY.MOPSTART - MOPACTIVITY.MOPAPPROVEDTIME BETWEEN 0 and 14)
WHERE TRUNC(TO_DATE(FIXED_MOP, 'MMDDYYHH24MISS'))
BETWEEN TRUNC(SYSDATE-90) AND TRUNC(SYSDATE)
ORDER BY "TIME_ORDER"
"""
def date = new Date()
def dts = date.format("yyyy-MM-dd-HH-mm-ss")
File file = new File('C:/Output/' + dts + ' EXPEDITE_MOPS.xls')
file.write("")
db.eachRow(sql) {
file.append(it.MOPID + "\t" + it.TYPE + "\n")
}
You need a semicolon after DROP TABLE TEMPXMOP24.

Creating a trend line from data set SQL

The code below returns the number of resolved tickets and the number of opened tickets for a period (period is YYYY,WW) going back a certain number of days. For example if #NoOfDays is 7:
resolved | opened | week | year | period
56 | 30 | 13 | 2012 | 2012, 13
237 | 222 | 14 | 2012 | 2012, 14
'resolved' and 'opened' are graphed on lines (y) over period (x). I would like to add another column 'trend' that would return a number that when graphed over period, will be a trend line (simple linear regression). I do want to use both sets of values as one data source for the trend.
This is the code I have:
SELECT a.resolved, b.opened, a.weekClosed AS week, a.yearClosed AS year,
CAST(a.yearClosed as varchar(5)) + ', ' + CAST(a.weekClosed as varchar(5)) AS period
FROM
(SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS resolved, { fn WEEK(date_closed) } AS weekClosed, { fn YEAR(date_closed) } AS yearClosed
FROM v_rpt_Service
WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - #NoOfDays, 0))
GROUP BY { fn WEEK(date_closed) }, { fn YEAR(date_closed) }) AS a
LEFT OUTER JOIN
(SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS opened, { fn WEEK(date_entered) } AS weekEntered, { fn YEAR(date_entered)
} AS yearEntered
FROM v_rpt_Service AS v_rpt_Service_1
WHERE (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - #NoOfDays, 0))
GROUP BY { fn WEEK(date_entered) }, { fn YEAR(date_entered) }) AS b ON a.weekClosed = b.weekEntered AND a.yearClosed = b.yearEntered
ORDER BY year, week
Edit:
According to serc.carleton.edu/files/mathyouneed/best_fit_line_dividing.pdf, it seems that I want to break the data in half, then calculate the average. Then I need to find the best fit line, and use the slope and the y-intercept to calculate the values needed to return in 'trend' using y = mx + b?
I know this is very possible in SQL, however, the program I am inserting the SQL into has limitations on what I can do.
The red and blue dots are the numbers I am returning now(opened and resolved). I need to return a value for every period in 'trend' in order to create the purple line. (this image is hypothetical)
I was interested in the problem, and I have found that the best way to grok a complex query is to reformat it using my own style and conventions. I applied them to your solution, and the result is below. I've no idea if this will have any value to you...
There were a few bits of code that I do not believe are part of the MS T-SQL syntax, such as ({fn xxx } and the WEEK(xxx) function.
This code compiles, but I can't run it as I don't have a data table properly configured.
I made a host of coding changes that would take a serious lot of explaining, and I'm going to skip most of that. Add a comment if you'd like anything explicated.
I tossed in a lot of whitespace. The difference between legible and illegible codes is often just the perception and sensibilities of the beholder, and you might hate my conventions.
Not sure what the final result set should be (i.e. which columns get returned)
Some further notes:
This query will not get items entered in a week if no items were also closed in that week
Weeks may be partial, e.g. not all seven days may be present (adjust #Interval to always including full weeks -- but what about odd numbered intervals?)
Multiply the count(*) values by 1.0 to convert them to floats early (avoids cast and integer math truncation)
Made it a cte to allow the earlier formulas to be replaced by symbols in the later formulas (at which point things became a lot more legible)
So here's what I came up with:
;WITH cte as (
select
c.period
,resolved_half1
,resolved_half2
,opened_half1
,opened_half2
,row = row_number() over(order by c.yearClosed, c.weekClosed)
,y1 = ((SUM(resolved_half1) + SUM(opened_half1)) - (SUM(resolved_half2) + SUM(opened_half2))) / ((count(resolved_half1) + count(opened_half1)) / 2)
,y2 = ((SUM(resolved_half2) + SUM(opened_half2)) / (count(resolved_half2) + COUNT (opened_half2)))
,x1 = ((count(c.period)) / 4)
,x2 = (((count(c.period)) / 4) * 3)
from (select
a.yearclosed
,a.weekClosed
,a.resolved_half1
,b.yearEntered
,b.weekEntered
,b.opened_half1
,cast(a.yearClosed as varchar(5)) + ', ' + cast(a.weekClosed as varchar(5)) period
from (-- Number of items per week that closed within #Interval
select
count(distinct TicketNbr) * 1.0 resolved_half1
,datepart(wk, date_closed) weekClosed
,year(date_closed) yearClosed
from v_rpt_Service
where date_closed >= #FullInterval
group by
datepart(wk, date_closed)
,year(date_closed) ) a
left outer join (-- Number of items per week that were entered within #Interval
select
count(distinct TicketNbr) * 1.0 opened_half1
,datepart(wk, date_entered) weekEntered
,year(date_entered) yearEntered
from v_rpt_Service
where date_entered >= #FullInterval
group by
datepart(wk, date_entered)
,year(date_entered) ) b
on a.weekClosed = b.weekEntered
and a.yearClosed = b.yearEntered) c
left outer join (select
d.yearclosed
,d.weekClosed
,d.resolved_half2
,e.yearEntered
,e.weekEntered
,e.opened_half2
,cast(yearClosed as varchar(5)) + ', ' + cast(weekClosed as varchar(5)) period
from (select
count(distinct TicketNbr) * 1.0 resolved_half2
,datepart(wk, date_closed) weekClosed
,year(date_closed) yearClosed
from v_rpt_Service
where date_closed >= #HalfInterval
group by
datepart(wk, date_closed)
,year(date_closed) ) d
left outer join (select
count(distinct TicketNbr) * 1.0 opened_half2
,datepart(wk, date_entered) weekEntered
,year(date_entered) yearEntered
from v_rpt_Service
where date_entered >= #HalfInterval
group by
datepart(wk, date_entered)
,year(date_entered) ) e
on d.weekClosed = e.weekEntered
and d.yearClosed = e.yearEntered ) f
on c.period = f.period
group by
c.period
,resolved_half1
,resolved_half2
,opened_half1
,opened_half2
,c.yearClosed
,c.weekClosed
)
SELECT
row
,Period
,x1
,y1
,x2
,y2
,m = ((y1 - y2) / (x1 - x2))
,b = (y2 - (((y1 - y2) / (x1 - x2)) * x2))
,trend = ((((y1 - y2) / (x1 - x2)) * (row)) + (y2 - (((y1 - y2) / (x1 - x2)) * x2)))
from cte
order by row
As an addenda, all of subquery "c" could be replaced with something like the following, and "f" with a slightly modified version. Better or worse performance depends on table size, indexing, and other imponderables.
select
datepart(wk, date_closed) weekClosed
,year(date_closed) yearClosed
,count (distinct case
when date_closed >= #FullInterval then TicketNbr
else null
end) resolved_half1
,count (distinct case
when date_entered >= #FullInterval then TicketNbr
else null
end) opened_half1
from v_rpt_Service
where date_closed >= #FullInterval
or date_entered >= #FullInterval
group by
datepart(wk, date_closed)
,year(date_closed)
I figured it out. I divided the data into multiple derived tables and sub queries, essentially dividing the data in half. These are my formulas to get each value:
*(each row is a week)*
y1 = average of data first half
y2 = average of data second half
x1 = 1/4 of number of weeks
x2 = 3/4 of number of weeks
m = (y1-y2)/(x1-x2)
b = y2 - (m * x2)
trend = (m * row_number) + b
And here is my (very dirty) SQL code:
SELECT resolved_half1,resolved_half2,opened_half1,opened_half2, c.period,
((SUM (resolved_half1) OVER () + SUM(opened_half1) OVER ()) - (SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ())) / ((COUNT(resolved_half1) OVER () + COUNT(opened_half1) OVER ()) / 2) as y1,
((SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ()) / (COUNT(resolved_half2) OVER () + COUNT (opened_half2) OVER ())) as y2,
((COUNT(c.period) OVER ()) / 4) as x1,
(((COUNT(c.period) OVER ()) / 4) * 3) as x2,
((CAST(((SUM (resolved_half1) OVER () + SUM(opened_half1) OVER ()) - (SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ())) / ((COUNT(resolved_half1) OVER () + COUNT(opened_half1) OVER ()) / 2) as float) - CAST(((SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ()) / (COUNT(resolved_half2) OVER () + COUNT (opened_half2) OVER ())) as float)) / (CAST(((COUNT(c.period) OVER ()) / 4) as float) - CAST( (((COUNT(c.period) OVER ()) / 4) * 3) as float))) as m,
(CAST(((SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ()) / (COUNT(resolved_half2) OVER () + COUNT (opened_half2) OVER ())) as float) - (((CAST(((SUM (resolved_half1) OVER () + SUM(opened_half1) OVER ()) - (SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ())) / ((COUNT(resolved_half1) OVER () + COUNT(opened_half1) OVER ()) / 2) as float) - CAST(((SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ()) / (COUNT(resolved_half2) OVER () + COUNT (opened_half2) OVER ())) as float)) / (CAST(((COUNT(c.period) OVER ()) / 4) as float) - CAST( (((COUNT(c.period) OVER ()) / 4) * 3) as float))) * (((COUNT(c.period) OVER ()) / 4) * 3))) as b,
((((CAST(((SUM (resolved_half1) OVER () + SUM(opened_half1) OVER ()) - (SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ())) / ((COUNT(resolved_half1) OVER () + COUNT(opened_half1) OVER ()) / 2) as float) - CAST(((SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ()) / (COUNT(resolved_half2) OVER () + COUNT (opened_half2) OVER ())) as float)) / (CAST(((COUNT(c.period) OVER ()) / 4) as float) - CAST( (((COUNT(c.period) OVER ()) / 4) * 3) as float))) * (ROW_NUMBER() OVER(ORDER BY c.yearClosed,c.weekClosed))) + (CAST(((SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ()) / (COUNT(resolved_half2) OVER () + COUNT (opened_half2) OVER ())) as float) - (((CAST(((SUM (resolved_half1) OVER () + SUM(opened_half1) OVER ()) - (SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ())) / ((COUNT(resolved_half1) OVER () + COUNT(opened_half1) OVER ()) / 2) as float) - CAST(((SUM(resolved_half2) OVER () + SUM(opened_half2) OVER ()) / (COUNT(resolved_half2) OVER () + COUNT (opened_half2) OVER ())) as float)) / (CAST(((COUNT(c.period) OVER ()) / 4) as float) - CAST( (((COUNT(c.period) OVER ()) / 4) * 3) as float))) * (((COUNT(c.period) OVER ()) / 4) * 3)))) as trend,
ROW_NUMBER() OVER(ORDER BY c.yearClosed,c.weekClosed) as row
FROM
(SELECT *, CAST(yearClosed as varchar(5)) + ', ' + CAST(weekClosed as varchar(5)) AS period
FROM (SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS resolved_half1, { fn WEEK(date_closed) } AS weekClosed, { fn YEAR(date_closed) } AS yearClosed
FROM v_rpt_Service
WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180), 0))
GROUP BY { fn WEEK(date_closed) }, { fn YEAR(date_closed) }) AS a
LEFT OUTER JOIN
(SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS opened_half1, { fn WEEK(date_entered) } AS weekEntered, { fn YEAR(date_entered)
FROM v_rpt_Service AS v_rpt_Service_1
WHERE (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180), 0))
GROUP BY { fn WEEK(date_entered) }, { fn YEAR(date_entered) }) AS b ON a.weekClosed = b.weekEntered AND a.yearClosed = b.yearEntered) as c
LEFT OUTER JOIN
(SELECT *, CAST(yearClosed as varchar(5)) + ', ' + CAST(weekClosed as varchar(5)) AS period
FROM (SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS resolved_half2, { fn WEEK(date_closed) } AS weekClosed, { fn YEAR(date_closed) } AS yearClosed
FROM v_rpt_Service
WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180 / 2), 0))
GROUP BY { fn WEEK(date_closed) }, { fn YEAR(date_closed) }) AS d
LEFT OUTER JOIN
(SELECT TOP (100) PERCENT COUNT(DISTINCT TicketNbr) AS opened_half2, { fn WEEK(date_entered) } AS weekEntered, { fn YEAR(date_entered)} AS yearEntered
FROM v_rpt_Service AS v_rpt_Service_1
WHERE (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - (180 / 2), 0))
GROUP BY { fn WEEK(date_entered) }, { fn YEAR(date_entered) }) AS e ON d.weekClosed = e.weekEntered AND d.yearClosed = e.yearEntered
) as f ON c.yearClosed = f.yearClosed AND c.weekClosed = f.weekClosed AND c.weekEntered = f.weekEntered AND c.yearEntered = f.yearEntered AND c.period = f.period
GROUP BY c.period, resolved_half1,resolved_half2,opened_half1,opened_half2,c.yearClosed,c.weekClosed
ORDER BY row
This code uses a hard coded value of 180 days. I still need to be able to use a varibale to select the number of days (without getting a divide by 0 error), and the code really needs to be cleaned up.
If someone can do those two things for me (I'm not the best at SQL), the bounty is theirs.
Image:
I believe that this will do the trick - if not post some actual sample data and I'll see if I can tweak it to fix it:
DECLARE #noOfDays INT
SET #noofdays = 180
;WITH tickets AS
(
SELECT DISTINCT
DATENAME(YEAR,date_closed) + RIGHT('000' + CAST(DATEPART(WEEK,date_closed) AS VARCHAR(5)),3) as Period
,ticket_nbr
,1 as ticket_type --resolved
FROM v_rpt_Service
WHERE (date_closed >= DateAdd(Day, DateDiff(Day, 0, GetDate()) - #NoOfDays, 0))
UNION ALL
SELECT DISTINCT
DATENAME(YEAR,date_closed) + RIGHT('000' + CAST(DATEPART(WEEK,date_closed) AS VARCHAR(5)),3) as Period
,ticket_nbr
,0 as ticket_type --opened
FROM v_rpt_Service
WHERE (date_entered > = DateAdd(Day, DateDiff(Day, 0, GetDate()) - #NoOfDays, 0))
)
,tickets2 AS
(
SELECT
Period
,SUM(CASE WHEN ticket_type = 0 THEN 1 ELSE 0 END) as opened
,SUM(CASE WHEN ticket_type = 1 THEN 1 ELSE 0 END) as closed
FROM tickets
GROUP BY
Period
)
,tickets3 AS
(
SELECT
Period
,row_number() OVER (ORDER BY period ASC) as row
,opened
,closed
,COUNT(period) OVER() as base
,SUM(opened) OVER () as [Sumopened]
,SUM(opened * opened) OVER () as [Sumopened^2]
,SUM(opened * closed) OVER () as [Sumopenedclosed]
,SUM(closed) OVER () as [Sumclosed]
,SUM(closed * closed) OVER () as [Sumclosed^2]
,SUM(opened * closed) OVER () * COUNT(period) OVER () AS [nSumopenedclosed]
,SUM(opened) OVER () * SUM(closed) OVER () AS [Sumopened*Sumclosed]
,SUM(opened * opened) OVER () * COUNT(period) OVER () AS [nSumopened^2]
,SUM(opened) OVER () * SUM(opened) OVER () as [Sumopened*Sumopened]
FROM tickets2
)
--Formula for linear regression is Y = A + BX
SELECT
period
,opened
,closed
,((1.0 / base) * [Sumclosed]) -
([Sumopenedclosed] - ([Sumopened*Sumclosed] / base)) / ([Sumopened^2] - ([Sumopened*Sumopened] / base)) *((1.0 / base) * [Sumopened])
+ row * ([Sumopenedclosed] - ([Sumopened*Sumclosed] / base)) / ([Sumopened^2] - ([Sumopened*Sumopened] / base))
AS trend_point
,((1.0 / base) * [Sumclosed]) -
([Sumopenedclosed] - ([Sumopened*Sumclosed] / base)) / ([Sumopened^2] - ([Sumopened*Sumopened] / base)) *((1.0 / base) * [Sumopened]) AS A
,([Sumopenedclosed] - ([Sumopened*Sumclosed] / base)) / ([Sumopened^2] - ([Sumopened*Sumopened] / base)) as B
from tickets3