Using CASE instead of using UNION in ORACLE SQL - sql

I have a query like this shown below
SELECT A.BUSINESS_UNIT
,A.ASSET_ID
,A.BOOK
,A.FISCAL_YEAR
,A.ACCOUNTING_PERIOD
,A.CATEGORY
,A.ACCOUNT_FA AS ACCOUNT
,A.CURRENCY_CD
,'COST_ADD' AS MOT
,A.COST_ADD AS AMOUNT
FROM SYSADM.PS_DEPR_RPT A
WHERE A.BOOK IN ('CORP-BASE','CORPORATE')
AND NOT (A.COST_ADD=0)
UNION
SELECT A1.BUSINESS_UNIT
,A1.ASSET_ID
,A1.BOOK
,A1.FISCAL_YEAR
,A1.ACCOUNTING_PERIOD
,A1.CATEGORY
,A1.ACCOUNT_AD AS ACCOUNT
,A1.CURRENCY_CD
,'ACCUM_DEPR_ADD' AS MOT
,A1.ACCUM_DEPR_ADD AS AMOUNT
FROM SYSADM.PS_DEPR_RPT A1
WHERE A1.BOOK IN ('CORP-BASE','CORPORATE')
AND NOT (A1.ACCUM_DEPR_ADD=0);
I want to remove the UNION which I have used in this to increase the performance of the query. As it is taking around 120sec to run the query, I want to make it more efficient. I used CASE for this. Query run time is less(4sec) but, i have a data mismatch here. Please help me on this.
PS: Query that I prepared using CASE is given below. Kindly suggest if any corrections required.
select BUSINESS_UNIT
,ASSET_ID
,BOOK
,FISCAL_YEAR
,ACCOUNTING_PERIOD
,CATEGORY
,ACCOUNT
,MOT
,AMOUNT
FROM
(SELECT A.BUSINESS_UNIT
,A.ASSET_ID
,A.BOOK
,A.FISCAL_YEAR
,A.ACCOUNTING_PERIOD
,A.CATEGORY
,A.ACCOUNT_FA AS ACCOUNT
,A.CURRENCY_CD,
case when NOT (A.COST_ADD=0) then 'COST_ADD'
when NOT (A.ACCUM_DEPR_ADD=0) then 'ACCUM_DEPR_ADD'
else 'x'
END
as MOT,
case when NOT (A.COST_ADD=0) then A.COST_ADD
when NOT (A.ACCUM_DEPR_ADD=0) then A.ACCUM_DEPR_ADD
else 0
END
as AMOUNT
FROM SYSADM.PS_DEPR_RPT A
WHERE A.BOOK IN ('CORP-BASE','CORPORATE')) X
where mot <> 'x' and amount <> 0;

You can try this.
SELECT
A.BUSINESS_UNIT
,A.ASSET_ID
,A.BOOK
,A.FISCAL_YEAR
,A.ACCOUNTING_PERIOD
,A.CATEGORY
,A.ACCOUNT_FA AS ACCOUNT
,A.CURRENCY_CD
,CASE WHEN A.COST_ADD <> 0 THEN 'COST_ADD' ELSE 'ACCUM_DEPR_ADD' END AS MOT
,CASE WHEN A.COST_ADD <> 0 THEN A.COST_ADD ELSE A.ACCUM_DEPR_ADD END AS AMOUNT
FROM SYSADM.PS_DEPR_RPT A
WHERE A.BOOK IN ('CORP-BASE','CORPORATE');

SELECT
A.BUSINESS_UNIT
,A.ASSET_ID
,A.BOOK
,A.FISCAL_YEAR
,A.ACCOUNTING_PERIOD
,A.CATEGORY
,A.ACCOUNT_FA AS ACCOUNT
,A.CURRENCY_CD
,CASE WHEN A.COST_ADD <> 0 THEN 'COST_ADD' ELSE 'ACCUM_DEPR_ADD' END AS MOT
,CASE WHEN A.COST_ADD <> 0 THEN A.COST_ADD ELSE A.ACCUM_DEPR_ADD END AS AMOUNT
FROM SYSADM.PS_DEPR_RPT A
WHERE A.BOOK IN ('CORP-BASE','CORPORATE')
and (A.COST_ADD <> 0 or A.ACCUM_DEPR_ADD <> 0);

Related

Query works in SQL Developer but doesn't work in Putty (ORA-00907, missing parenthesis)

Can you see any telltale signs what this code is missing? I am sorry if this is too long. This is a full outer join of two segments, MTD and YTD. The results are expected are comma delimited. This works perfectly in SQL Developer but not in Unix (Putty).
select mtd.portfolio||','||
mtd.descr||','||
mtd.ccy||','||
CASE WHEN ytd.ytd_amnt IS NOT NULL THEN
CASE WHEN substr(mtd.acnt,1,1) in ('2','5','0') --base currency month to date
THEN (sum(ytd.ytd_amnt_bc) - sum(mtd.mtd_amnt_bc))*-1
ELSE (sum(ytd.ytd_amnt_bc) - sum(mtd.mtd_amnt_bc))
END
ELSE
0
END
||','||
CASE WHEN mtd.ccy in ('USD') THEN
CASE WHEN substr(mtd.acnt,1,1) in ('2','5','0') THEN --base currency year to date
sum(mtd.mtd_amnt)*-1
ELSE
sum(mtd.mtd_amnt)
END
ELSE
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN
sum(mtd.mtd_amnt_bc)*-1
ELSE
sum(mtd.mtd_amnt_bc)
END
END
||','||
CASE WHEN ytd.ytd_amnt IS NOT NULL THEN
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN --native currency month to date
(sum(ytd.ytd_amnt) - sum(mtd.mtd_amnt)) *-1
ELSE
sum(ytd.ytd_amnt) - sum(mtd.mtd_amnt)
END
ELSE
0
END||','||
CASE WHEN mtd.ccy in ('PHP') THEN --native currency year to date
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN
mtd.mtd_amnt*-1
ELSE
mtd.mtd_amnt
END
ELSE
CASE WHEN substr(mtd.acnt,1,1)in ('2','5','0') THEN
sum(mtd.mtd_amnt_bc)*-1
ELSE
sum(mtd.mtd_amnt_bc)
END
END||','||
CASE WHEN substr(mtd.acnt,1,1)='0'
THEN '5'
ELSE substr(mtd.acnt,1,1)
END
from
(select (accl.acnt) acnt, (kp.account) portfolio, (accc.descr)descr, (accl.curr) ccy, sum(accl.amnt_bc) mtd_amnt_bc, sum(accl.amnt) mtd_amnt
from acc$ledger accl
LEFT JOIN k$portfolio kp ON kp.id = accl.portfolio
LEFT JOIN acc$chart accc ON accc.acnt = accl.acnt
where accl.company = accc.company
and accl.company <> 1
and substr(accl.acnt,1,1) in ('0','1','2','5')
and accc.fisc_yr in (select to_char(current_business_date,'YYYY') from k$company where id=1)
and accl.account_dte <> to_date('0001-01-01','YYYY-MM-DD')
and accl.dt <= (select last_day(add_months(current_business_date,-1)) from k$company where id=1)
group by accc.descr, kp.account, accl.acnt, accl.curr
order by kp.account, accl.acnt
)
mtd full outer join
(select (accl.acnt) acnt, (kp.account) portfolio, (accc.descr)descr, sum(accl.amnt_bc) ytd_amnt_bc, sum(accl.amnt) ytd_amnt
from acc$ledger accl
LEFT JOIN k$portfolio kp ON kp.id = accl.portfolio
LEFT JOIN acc$chart accc ON accc.acnt = accl.acnt
where accl.company = accc.company
and accl.company <> 1
and substr(accl.acnt,1,1) in ('0','1','2','5')
and accc.fisc_yr in (select to_char(current_business_date,'YYYY') from k$company where id=1)
and accl.account_dte <> to_date('0001-01-01','YYYY-MM-DD')
and accl.dt <= (select last_day(add_months(current_business_date,-2)) from k$company where id=1)
group by accc.descr, kp.account, accl.acnt
order by kp.account, accl.acnt)
ytd
on mtd.portfolio=ytd.portfolio
and mtd.descr=ytd.descr
and mtd.acnt= ytd.acnt
group by mtd.acnt, mtd.portfolio, mtd.descr, mtd.ccy, mtd.mtd_amnt, ytd.ytd_amnt
order by mtd.portfolio, mtd.acnt, mtd.descr;
Remove the empty newline. By default SQL*Plus uses empty newlines to terminate a SQL statement. SQL Developer does not work the same way, depending on how you run the query.

Is it possible to use 'case' with and in 'count'?

Is it possible to use case with and in count
SELECT branches.NAME AS agence,
count(
CASE loanstatus
WHEN '1'
AND Datepart(month,loanaccount.issuedate)= 2 THEN 1
ELSE NULL
END )AS nombre_de_credits_demande ,
count(
CASE loanstatus
WHEN '2' datepart(month,loanaccount.chargeoffdate)= 2 THEN 1
ELSE NULL
END )AS nombre_de_credits_approuve
please help me
You can use it with count(). I prefer sum():
select Branches.Name as Agence,
sum(case when LoanStatus = '1' and
datepart(MONTH, LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Demandé ,
sum(case when LoanStatus = '2' and
datepart(MONTH, LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Approuvé
The issue with your code was not the count() versus sum() it is the mixing of two different case syntaxes. When you use case <var> when <val>, you cannot include any other conditions. Just use when with the full conditions that you want.
And, if you like, you can use count() instead of sum().
And, for conciseness, I prefer the month() function:
select Branches.Name as Agence,
sum(case when LoanStatus = '1' and MONTH(LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Demandé ,
sum(case when LoanStatus = '2' and MONTH(LoanAccount.IssueDate) = 2
then 1 else 0
end ) as Nombre_de_Crédits_Approuvé
you can achieve your goal through this query.
select
branches.name as agence
,(select COUNT(1) from <table_name> where loginstatus=1 and Datepart(month,loanaccount.issuedate)= 2) as nombre_de_credits_demande
,(select COUNT(1) from <table_name> where loginstatus=2 and Datepart(month,loanaccount.issuedate)= 2) as AS nombre_de_credits_approuve
from <Table_name>

SQL Query using calculation in SELECT not working

the purpose of this query is to take the percentage of late orders to total number of orders. So the calculation part of this query is only pulling back zeros. Everything else works. I commented the part below that is pulling back zeros. What am I doing wrong?
SELECT
case LM.DState
WHEN 'OH' THEN 'OH Order'
WHEN 'NC' THEN 'NC Order'
WHEN 'TX' THEN 'TX Order'
WHEN 'WA' THEN 'WA order'
Else 'Other'
End as 'OrderType',
count(LM.OrderID) as 'Vol',
sum(case
WHEN datediff(day, S.Appt, S.Arrived) > 0 THEN 1
else 0
END) as 'TotalLates',
--PART THAT IS ONLY PULLING ZEROS, SHOULD BE NON-ZERO
CAST (
sum(case WHEN datediff(day, S.Appt, S.Arrived) > 0 THEN 1 else 0 END)
/ count(LM.OrderID)
as decimal(5,2)
) *100 as 'OTD%'
FROM ((Customers.dbo.CusOrders as LM WITH (NOLOCK) inner join
Customers.dbo.CusLocations as S WITH (NOLOCK) on LM.OrderID = S.OrderID) inner join
Customers.dbo.Loads as L with (NOLOCK) on LM.OrderID = L.OrderID)
WHERE LM.CusCode = 'Domestic'
GROUP BY case LM.DState
WHEN 'OH' THEN 'OH Order'
WHEN 'NC' THEN 'NC Order'
WHEN 'TX' THEN 'TX Order'
WHEN 'WA' THEN 'WA Order
Else 'Other'
End
It's due to rounding that occurs with integer division, since you're calculating a percentage the value is always below 1, and that gets rounded to 0, you can fix this by multiplying the numerator by 1.0:
CAST (
sum(case WHEN datediff(day, S.Appt, S.Arrived) > 0 THEN 1 else 0 END)*1.0
/ count(LM.OrderID)
as decimal(5,2)
) *100 as 'OTD%'
For example:
SELECT 5/7
--0
SELECT 5.0/7
--0.714285

SQL group join table

Hi I want to display out the record in the format as below. How to I display the format as below ?
Branch Total Payment Total Discount Total Net Payment
A 10,000 2,000 8,000
B 29,190 1,540 27,656
Here are my query for the above. Please help me. Thanks.
SELECT TranID, ProjCode,
CASE WHEN IsActive='N' THEN 'Cancellation' ELSE PaymentType END As PaymentType,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale END) END As Sale ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale_Before_CutOff END) END As Sale_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net END) END As Net ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net_Before_CutOff END) END As Net_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN Net ELSE 0 END As Withdrawal,
CASE WHEN PaymentType='Withdrawal' THEN Net_Before_CutOff ELSE 0 END As Withdrawal_Before_CutOff,
CASE WHEN IsActive='N' THEN Net ELSE 0 END As Cancellation,
CASE WHEN IsActive='N' THEN Net_Before_CutOff ELSE 0 END As Cancellation_Before_CutOff,
CASE WHEN IsActive='N' THEN 0 ELSE Discount END As Discount,
CASE WHEN IsActive='N' THEN 0 ELSE Discount_Before_CutOff END As Discount_Before_CutOff, AdditionalCommission,AdditionalCommission_Before_CutOff, Remark, UserStamp, BusinessDay,
TranDate, BranchID, StaffCode, IsActive,Quantity
FROM
(SELECT c.INTERNAL_TRAN_NUM AS TranID, c.PROJECT_CODE AS ProjCode, c.PAYMENT_TYPE AS PaymentType,d.QUANTITY As Quantity,
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale,
CASE WHEN DATEPART(hh, c.TRAN_DATE)<= DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale_Before_CutOff,
CASE WHEN DATEPART(hh, c.TRAN_DATE)> DATEPART(hh, f.CUT_OFF_TIME) THEN c.NET_PAYMENT ELSE 0 END AS Net,
CASE WHEN DATEPART(hh, c.TRAN_DATE) <= DATEPART(hh,f.CUT_OFF_TIME) THEN c.NET_PAYMENT ELSE 0 END AS Net_Before_CutOff,
CASE WHEN DATEPART(hh, c.TRAN_DATE) > DATEPART(hh,f.CUT_OFF_TIME) THEN c.DISCOUNT_AMOUNT ELSE 0 END AS Discount,
CASE WHEN DATEPART(hh, c.TRAN_DATE) <= DATEPART(hh,f.CUT_OFF_TIME) THEN c.DISCOUNT_AMOUNT ELSE 0 END AS Discount_Before_CutOff,
CASE WHEN DATEPART(hh, c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN d.USER_DEF8 ELSE 0 END As AdditionalCommission,
CASE WHEN DATEPART(hh, c.TRAN_DATE) <= DATEPART(hh, f.CUT_OFF_TIME) THEN d.USER_DEF8 ELSE 0 END As AdditionalCommission_Before_CutOff,
c.REMARKS AS Remark, c.USER_STAMP AS UserStamp,CAST(DATEADD(hh, - DATEPART(hh, f.CUT_OFF_TIME), c.TRAN_DATE) AS DATE) AS BusinessDay,
c.TRAN_DATE AS TranDate, e.BRANCH_ID AS BranchID, d.STAFF_CODE AS StaffCode, c.ISACTIVE AS IsActive
FROM SC_TRAN_HEADER AS c
INNER JOIN SC_TRAN_DETAIL AS d ON d.INTERNAL_TRAN_NUM = c.INTERNAL_TRAN_NUM
INNER JOIN SC_BRANCH AS e ON c.BRANCH_NUM = e.INTERNAL_NUM
INNER JOIN SC_COMMISSION AS f ON f.BRANCH_NUM = c.BRANCH_NUM) AS TMP
The best that I can come up with, based on the information in your question, is:
with cte as (<your query here>)
select branchid, sum(sale) as payment, sum(discount) as discount,
sum(sale) - sum(discount)
from cte
group by branchid;
If this is not correct, then edit your question to provide more information to help resolve your question.
FIRST, I would try to simplify the readability of this query from all the case/when conditions. First, you do case/when in your preliminary query on repeated tests to get before and after cut-off period, then others you do based on withdrawal or NOT withdrawal and yet again for Active vs Not Active.
Simple math multipliers... consider your query segment... your inner query to get the values of Sale and Sale_Before_CutOff.
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale,
CASE WHEN DATEPART(hh, c.TRAN_DATE)<= DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale_Before_CutOff,
Both test the date part for the cutoff time, and the answer can be Before, or After, never both. You do the same tests for Net, Net_Before_Cutoff, Withdrawal, Withdrawal_Before_Cutoff.
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net END) END As Net ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net_Before_CutOff END) END As Net_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN Net ELSE 0 END As Withdrawal,
CASE WHEN PaymentType='Withdrawal' THEN Net_Before_CutOff ELSE 0 END As Withdrawal_Before_CutOff,
THEN, in your main part of the query, you are applying yet again a nested case/when(case/when)
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale END) END As Sale ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale_Before_CutOff END) END As Sale_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net END) END As Net ,
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Net_Before_CutOff END) END As Net_Before_CutOff ,
CASE WHEN PaymentType='Withdrawal' THEN Net ELSE 0 END As Withdrawal,
CASE WHEN PaymentType='Withdrawal' THEN Net_Before_CutOff ELSE 0 END As Withdrawal_Before_CutOff,
What I would do, is from your subquery qualifying records, I would get the raw amount columns and 6 flags to act as multiplers.
SELECT ...
c.TOTAL_PAYMENT,
c.Net_Payment,
c.Discount_Amount,
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME)
THEN 1 ELSE 0 END as AfterMult,
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME)
THEN 0 ELSE 1 END as BeforeMult,
CASE WHEN c.PaymentType='Withdrawal'
THEN 1 ELSE 0 END as WithdrawalMult,
CASE WHEN c.PaymentType='Withdrawal'
THEN 0 ELSE 1 END as NotAWithdrawalMult,
CASE WHEN c.IsActive='N'
THEN 1 ELSE 0 END As NotActiveMult,
CASE WHEN c.IsActive='N'
THEN 0 ELSE 1 END As ActiveMult, ...
Notice, the same condition is applied to both parts, only the THEN/ELSE swaps the multiplier from a 1 to 0 respectively to what it should represent. So, for any given record, example result would be
Total_Payment Net_Payment Discount_Amount AfterMult BeforeMult WithdrawalMult NotAWithdrawalMult NotActiveMult ActiveMult
100 86 14 1 0 1 0 0 1
200 170 30 0 1 0 1 1 0
Now, simple thoughts... if you want to know how much total payments were before a cutoff and were NOT withdrawls, in your upper query it would be
Total_Payment * BeforeMult * NotAWithdrawal = TotalPayments_BeforeCutoff
vs payments AFTER cutoff
Total_Payment * AfterMult * NotAWithdrawal = TotalPayments_BeforeCutoff
Similar consideration for your Active vs Not active. Use that multiplier, no sense in doing nested cases when you already have determined its status when pulling the records. Lets take a look at your "Sale" column... The inner query getting the record is using the "Total_Payment" field
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME) THEN c.TOTAL_PAYMENT ELSE 0 END AS Sale,
then in the upper is a nested case/when.
CASE WHEN PaymentType='Withdrawal' THEN 0 ELSE (CASE WHEN IsActive='N' THEN 0 ELSE Sale END) END As Sale ,
The only time you care about the sale amount is when it is AFTER the cutoff, is NOT a withdrawal and when it IS Active, so just multiply those flags
Total_Payment * AfterMult * NotAWithdrawalMult * ActiveMult as Sale
Total_Payment * BeforeMult * NotAWithdrawalMult * ActiveMult as Sale_Before_Cutoff
Finally, you have so many other columns in the table being pulled and not used, why keep them. And for what you are trying to get the SUM() of, its going to be much easier to read it something like
SUM( Total_Payment * AfterMult * NotAWithdrawalMult * ActiveMult ) as TotalSale
SUM( Total_Payment * BeforeMult * NotAWithdrawalMult * ActiveMult ) as TotalSale_Before_Cutoff
All that being said, I offer you this... please confirm context, but should make sense from above. Also, note, the last 3 column I added were the final total you are probably looking for where the summation did not care as to before or after the time cutoff... just the fact it was a valid payment/discount/net, was Active, and on two of them was NOT a withdrawal... Seeing this, you would need to confirm its accuracy. The first 6 summations show based on respective after cutoff (no column name suffix) vs BEFORE the cutoff (column name HAS the suffix)
SELECT
PQ.Branch_Name, <-- CONFIRM COLUMN FROM PreQuery (PQ alias)
SUM( PQ.Total_Payment * PQ.AfterMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as TotalSale,
SUM( PQ.Total_Payment * PQ.BeforeMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as TotalSale_BeforeCutoff,
SUM( PQ.Discount_Amount * PQ.AfterMult * PQ.ActiveMult ) as TotalDiscount,
SUM( PQ.Discount_Amount * PQ.BeforeMult * PQ.ActiveMult ) as TotalDiscount_BeforeCutoff,
SUM( PQ.Net_Payment * PQ.AfterMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as Net,
SUM( PQ.Net_Payment * PQ.BeforeMult * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as Net_BeforeCutoff,
SUM( PQ.Total_Payment * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as TotalSaleAll,
SUM( PQ.Discount_Amount * PQ.ActiveMult ) as TotalDiscountAll,
SUM( PQ.Net_Payment * PQ.NotAWithdrawalMult * PQ.ActiveMult ) as NetAll
from
( select
e.Branch_Name, <-- GUESSING ON THIS COLUMN FOR ACTUAL BRANCH
c.Total_Payment,
c.Net_Payment,
c.Discount_Amount,
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME)
THEN 1 ELSE 0 END as AfterMult,
CASE WHEN DATEPART(hh,c.TRAN_DATE) > DATEPART(hh, f.CUT_OFF_TIME)
THEN 0 ELSE 1 END as BeforeMult,
CASE WHEN c.PaymentType='Withdrawal'
THEN 1 ELSE 0 END as WithdrawalMult,
CASE WHEN c.PaymentType='Withdrawal'
THEN 0 ELSE 1 END as NotAWithdrawalMult,
CASE WHEN c.IsActive='N'
THEN 1 ELSE 0 END As NotActiveMult,
CASE WHEN c.IsActive='N'
THEN 0 ELSE 1 END As ActiveMult
FROM
SC_TRAN_HEADER AS c
INNER JOIN SC_TRAN_DETAIL AS d
ON c.INTERNAL_TRAN_NUM = d.INTERNAL_TRAN_NUM
INNER JOIN SC_BRANCH AS e
ON c.BRANCH_NUM = e.INTERNAL_NUM
INNER JOIN SC_COMMISSION AS f
ON c.BRANCH_NUM = f.BRANCH_NUM ) AS PQ
group by
PQ.Branch_Name <-- AGAIN, confirm column name here

Oracle SQL Expression to Sum Payments for Six Months based on Selected Month

Basically what I'm trying to do is calculate the average percentage of CreditPayments and the average percentage of CashPayments over a projected period (Lookback 3 months then total all paymnents of the correct type in the previous six months)
So if Average (During Correct Lookback Period) was = 75% Credit & 25% Cash then for my outstanding A/R for that month I could anticapte what % will be Credit & what % will be cash. I'd like to run it for a 12 month period with the lookback changing for each MOS.
Right now my result is always 0, which is obviously wrong. I know the initial inner query is correct; however, the problem happens when the outer query runs. I think the problem lies with the T1. MOS, which I think is limiting the results. Any help would be greatly appreciated.
SELECT
T1.Facility Facility
, T1.CustType CustType
, T1.MOS MOS
, SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.CredPmts ELSE 0 END)/SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.Charges ELSE 0 END)
, SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.CashPmts ELSE 0 END)/SUM(CASE WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1) THEN T1.Charges ELSE 0 END)
FROM
(
SELECT
T.FACILITY Facility
, T.CUSTTYPE CustType
, trunc(to_date(T.SERVICEDATE,'j'),'MONTH') MOS
, SUM(CASE WHEN T.TYPE = 'C' THEN T.AMOUNT ELSE 0 END) Charges
, SUM(CASE WHEN (T.TYPE IN ('P1','62','12','75','P6','23') THEN T.AMOUNT ELSE 0 END CredPmts
, SUM(CASE WHEN (T.TYPE IN ('92','57','P3','P9','26','39') THEN T.AMOUNT ELSE 0 END CashPmts
FROM TRANSTABLE T
WHERE
T.FACILITY = '123'
AND T.SERVICEDATE BETWEEN to_char(ADD_MONTHS(to_date('20120101', 'yyyymmdd'),-9), 'j') AND to_char(to_date('20121231', 'yyyymmdd'), 'j')
GROUP BY
T.FACILITY
, T.CUSTTYPE
, trunc(to_date(T.SERVICEDATE,'j'),'MONTH')
)T1
GROUP BY
T1.Facility
, T1.CustType
, T1.MOS
There are mismatched parenthesis in the CASE WHEN clause of the outer query:
WHEN (T1.MOS BETWEEN ADD_MONTHS(T1.MOS,-9) AND (ADD_MONTHS(T1.MOS,-3)-1))
all four places. Can you check it?