Missing Right Parenthesis error while executing this query in oracle - oracle

I am executing this query in oracle and it is giving me an error of missing right parenthesis at line 33. Is there anyone who can help me resolve this issue. Thank you
Here is my query
WITH t AS (
SELECT RM_LIVE.EMPLOYEE.EMPNO,
RM_LIVE.EMPNAME.FIRSTNAME,
RM_LIVE.EMPNAME.LASTNAME,
RM_LIVE.CRWBASE.BASE,
RM_LIVE.CRWCAT.crwcat,
RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC
FROM RM_LIVE.EMPBASE,
RM_LIVE.EMPLOYEE,
RM_LIVE.CRWBASE,
RM_LIVE.EMPNAME,
RM_LIVE.CRWSPECFUNC,
RM_LIVE.EMPSPECFUNC,
RM_LIVE.EMPQUALCAT,
RM_LIVE.CRWCAT
where RM_LIVE.EMPBASE.IDEMPNO = RM_LIVE.EMPLOYEE.IDEMPNO
AND RM_LIVE.EMPBASE.IDCRWBASE = RM_LIVE.CRWBASE.IDCRWBASE
AND RM_LIVE.EMPLOYEE.IDEMPNO = RM_LIVE.EMPNAME.IDEMPNO
AND RM_LIVE.EMPSPECFUNC.IDCRWSPECFUNC =RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC
AND RM_LIVE.EMPSPECFUNC.IDEMPNO =RM_LIVE.EMPLOYEE.IDEMPNO
AND RM_LIVE.EMPQUALCAT.IDEMPNO=RM_LIVE.EMPLOYEE.IDEMPNO
AND RM_LIVE.CRWCAT.IDCRWCAT = RM_LIVE.EMPQUALCAT.IDCRWCAT
AND RM_LIVE.CRWCAT.crwcat IN ('CP','FO','CM','MC')
AND RM_LIVE.CRWBASE.BASE <> 'XYZ'
AND RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC IN
('921','2' ,'1','301','17','4','3','7','302' ,'861','31',
'723','30','722 ','29 ','721','16','601','581')
AND RM_LIVE.EMPBASE.STARTDATE <= SYSDATE
AND RM_LIVE.EMPBASE.ENDDATE >= SYSDATE
AND RM_LIVE.EMPSPECFUNC.STARTDATE <= SYSDATE
AND RM_LIVE.EMPSPECFUNC.ENDDATE >= SYSDATE
AND RM_LIVE.EMPNAME.FROMDATE <=SYSDATE
AND RM_LIVE.EMPQUALCAT.STARTDATE <= SYSDATE
AND RM_LIVE.EMPQUALCAT.ENDDATE >= SYSDATE AS ta (EMPNO,EMPFIRSTNAME,EMPLASTNAME, Base, CAT, code)
)
SELECT DISTINCT
t.EMPNO,
t.EMPFIRSTNAME,
t.EMPLASTNAME,
t.Base,
t.CAT,
(ABS(oa.val1) * NVL(NULLIF((ABS(oa.val2) * ABS(oa.val3)),0),1) * ABS(oa.val4) * ABS(oa.val5) * ABS(oa.val6) * ABS(oa.val7) * ABS(oa.val8) * ABS(oa.val9)) AS "FTE VALUE"
FROM t
OUTER APPLY (SELECT MAX(CASE WHEN t2.code IN (1,2,4) THEN 0.70 ELSE -1 END) AS val1,
MAX(CASE WHEN t2.code IN (1,2) THEN 0 ELSE -1 END) AS val2,
MAX(CASE WHEN t2.code IN (4) THEN 1.29 ELSE -1 END) AS val3,
MAX(CASE WHEN t2.code IN ( 861 ) THEN 0.80 ELSE -1 END) AS val4
MAX(CASE WHEN t2.code IN (921,301,30,722,601,581) THEN 0.50 ELSE -1 END) AS val5
MAX(CASE WHEN t2.code IN (17,302,16) THEN 0.85 ELSE -1 END) AS val6
MAX(CASE WHEN t2.code IN (29,721) THEN 0.25 ELSE -1 END) AS val7
MAX(CASE WHEN t2.code IN (31,723) THEN 0.75 ELSE -1 END) AS val8
MAX(CASE WHEN t2.code IN (3,7) THEN 0.90 ELSE -1 END) AS val9
FROM t AS t2 WHERE t2.EMPNO = t.EMPNO) oa

The last line of your sub-query factoring (WITH ... AS ( ... )) clause is:
AND RM_LIVE.EMPQUALCAT.ENDDATE >= SYSDATE AS ta (EMPNO,EMPFIRSTNAME,EMPLASTNAME, Base, CAT, code)
The AS ta (...) is invalid syntax.
If you want to name the columns then you need to delete that part and change the first line to:
WITH t (EMPNO,EMPFIRSTNAME,EMPLASTNAME, Base, CAT, code) AS (
However, that is syntax introduced in Oracle 11g and won't work in Oracle 10g - if you want to support that version (and it seems you do since you've tagged it) then just explicitly alias each column:
WITH t AS (
SELECT RM_LIVE.EMPLOYEE.EMPNO,
RM_LIVE.EMPNAME.FIRSTNAME AS EMPFIRSTNAME,
RM_LIVE.EMPNAME.LASTNAME AS EMPLASTNAME,
RM_LIVE.CRWBASE.BASE,
RM_LIVE.CRWCAT.crwcat AS CAT,
RM_LIVE.CRWSPECFUNC.IDCRWSPECFUNC AS CODE

Related

Count and Sum inside a select with multiple sums and counts

I'm using sub-query factoring and I have a query that returns invoice lines, and in the end I have this final sub-query:
I've already tried Partition but without success
SELECT
COUNT(CASE WHEN PC <> 0 THEN 1 END) AS A_LINECOUNT,
SUM(CASE WHEN PC > 0 THEN NR ELSE 0 END) AS B_PRODUCTCOUNT,
COUNT(CASE WHEN ALLOW_PAY = 1 THEN 1 END) AS C_INVOICECOUNT, --- ERROR
SUM(CASE WHEN ALLOW_PAY = 1 THEN MISSING_VALUE ELSE 0 END) AS D_INVOICETOTAL, --- ERROR
COUNT(CASE WHEN IS_NON_LIQUIDABLE_PRODUCT = 1 THEN 1 END) AS E_CONDITIONCOUNT,
COUNT(CASE WHEN IS_LIQUIDABLE_PRODUCT = 1 THEN 1 END) AS F_CONDITIONCOUNT
FROM MAIN_Q
The calculation of C_INVOICECOUNT and D_INVOICETOTAL is not correct because their values are repeated within each line of the invoice. Please consider that um MAIN_Q i also have a document_id where i can group by.
thanks
Maybe I understood correctly, maybe not, but this is too long for comment. If yes, C_INVOICECOUNT can be count as:
count(distinct case when allow_pay = 1 then document_id end)
But the problem is with D_INVOICETOTAL. You have repeated values for each invoice here and details which do not repeat. If so, add row numbering to your query:
select main_q.*, row_number() over (partition by document_id) rn from main_q
and then in problematic places use rn = 1:
select ...
count(case when rn = 1 and allow_pay = 1 then 1 end),
sum(case when rn = 1 and allow_pay = 1 then missing_value else 0 end)
...
from (select main_q.*, row_number() over (partition by document_id) rn from main_q)
Only first rows for each invoice will be analysed. Of course you can add row_number in earlier step.

WITH Clause no longer working. "exceeded call limit on IO usage"

I have some code that previously ran fine with no issues. But now when I run I receive the
ORA-02395: exceeded call limit on IO usage
02395. 00000 - "exceeded call limit on IO usage"
error. Can anyone explain to me why my code is throwing this error. I have no access to increase any user privileges. I've tried running this code and limiting the amount of data in the with clause and it ran fine. So I'm guessing some modifications need to happen there.
WITH NEW_REP_DATA AS (
select period,manager rep,comp,sum(a) "GT99",sum(b) "90TO99",sum(c) "80TO89",sum(d) "70TO79",sum(e) "LT70",sum(f) "NA" from (
select period
,rep_code
,manager
--,nvl(a,0)+nvl(b,0)+nvl(c,0)+nvl(d,0)+nvl(e,0)+nvl(f,0) cnt
,comp,
nvl(a,0) a,nvl(b,0) b, nvl(c,0) c, nvl(d,0) d,nvl(e,0) e,nvl(f,0) f
from
(select period,rep_code,manager, comp,max(case when bucket='>99' then cnt end) a,
max(case when bucket='90TO99' then cnt end) b,
max(case when bucket='80TO89' then cnt end) c,
max(case when bucket= '70TO79' then cnt end) d,
max(case when bucket='LT70' then cnt end) e,
max(case when bucket='NA' then cnt end) f
from (
select period,rep_code,manager, comp,bucket,
--count(unique rep_code)
count( distinct rep_code) cnt
--cnt
from(
select * from (select
unique period
,MANAGER
,"PayeeID" rep_code
,comp
,cytd cytd_a
,cytp cytd_p,
nvl(case when cytp > 0 then
case when round((cytd/cytp),3) > .99 then '>99'
when round((cytd/cytp),3) between .891 and .99 then '90TO99'
when round((cytd/cytp),3) between .791 and .89 then '80TO89'
when round((cytd/cytp),3) between .7 and .79 then '70TO79'
when round((cytd/cytp),3) < .7 then 'LT70'
end
when cytp = 0 and cytd > 0 then '>99'
else 'NA'
end,'NA') as bucket
from (
select aaa.period
,aaa."PayeeID"
,aaa."Reports_to" MANAGER
,aaa."Component" comp,
aaa."Current_YTD_Actual" cytd,
aaa."Current_YTD_Plan" cytp
from nbr_var_data aaa
where aaa."Comp_Plan_Name" not in ('MISC_COMP','GM_2017')
AND "Comp_Plan_Name" not in ('MISC_COMP')
AND "Comp_Plan_Name" not LIKE '%GM%'
and aaa.period = (select max(aaa.period) from Nbr_Var_Data)
))
)
where 1=1
group by period, rep_code, comp, bucket, manager )
group by period, rep_code, comp, manager )) group by period, manager, comp)
SELECT DISTINCT
dc.rep PID
,dc.period
,ee.PAYEE_NAM
,dc.comp
,Dc."GT99"
,Dc."90TO99"
,Dc."80TO89"
,Dc."70TO79"
,Dc."LT70"
,Dc."NA"
,Ee.Parent_Payee_Id REPORT_TO_PAYEE_ID
,Ee.Parent_Payee_Nam REPORT_TO_NAME
FROM (SELECT
--period ,
--empl_id ,
gg.payee_id ,
gg.payee_nam ,
--lvl ,
ff.parent_payee_id ,
ff.PARENT_PAYEE_NAM
--parent_lvl ,
--mnth_disp
FROM (SELECT DISTINCT
dd.period
,dd.PARENT_PAYEE_ID
,ee.PAYEE_NAM PARENT_PAYEE_NAM
from (
SELECT DISTINCT
PERIOD,
PARENT_PAYEE_ID
FROM FI_CHANNEL_HIER) dd
left join FI_CHANNEL_HIER ee
on dd.PARENT_PAYEE_ID = ee.PAYEE_ID
WHERE DD.PERIOD = (select max(DD.PERIOD) from FI_CHANNEL_HIER )) ff
LEFT JOIN FI_CHANNEL_HIER gg
ON ff.PARENT_PAYEE_ID = gg.PARENT_PAYEE_ID) ee,
NEW_REP_DATA dc
WHERE EE.PAYEE_ID = DC.Rep
;
ORA-02395 happens when your query exceeds the LOGICAL_READS_PER_CALL threshold set in your user profile. That's why the issue goes away when you restricted the amount of data returned by your subquery.
Two possible explanations for why this did not use to happen:
The tables contain more data than they used to be.
Your DBA has implemented a new user profile (or made the existing one stricter).
The obvious solution is to negotiate with the DBA.
Otherwise you will need to refactor your query to reduce the number of blocks it scans. Doing requires an understanding of your data model, your business logic and your data characteristics (volume, distribution, usage).
Clearly that requires knowledge of and access to your system, so it's not something that we can help with.
WITH NEW_REP_DATA AS (
select period,manager rep,comp,sum(a) "GT99",sum(b) "90TO99",sum(c) "80TO89",sum(d) "70TO79",sum(e) "LT70",sum(f) "NA" from (
select period
,rep_code
,manager
--,nvl(a,0)+nvl(b,0)+nvl(c,0)+nvl(d,0)+nvl(e,0)+nvl(f,0) cnt
,comp,
nvl(a,0) a,nvl(b,0) b, nvl(c,0) c, nvl(d,0) d,nvl(e,0) e,nvl(f,0) f
from
(select period,rep_code,manager, comp,max(case when bucket='>99' then cnt end) a,
max(case when bucket='90TO99' then cnt end) b,
max(case when bucket='80TO89' then cnt end) c,
max(case when bucket= '70TO79' then cnt end) d,
max(case when bucket='LT70' then cnt end) e,
max(case when bucket='NA' then cnt end) f
from (
select period,rep_code,manager, comp,bucket,
--count(unique rep_code)
count( distinct rep_code) cnt
--cnt
from(
select * from (select
unique period
,MANAGER
,"PayeeID" rep_code
,comp
,cytd cytd_a
,cytp cytd_p,
nvl(case when cytp > 0 then
case when round((cytd/cytp),3) > .99 then '>99'
when round((cytd/cytp),3) between .891 and .99 then '90TO99'
when round((cytd/cytp),3) between .791 and .89 then '80TO89'
when round((cytd/cytp),3) between .7 and .79 then '70TO79'
when round((cytd/cytp),3) < .7 then 'LT70'
end
when cytp = 0 and cytd > 0 then '>99'
else 'NA'
end,'NA') as bucket
from (
select aaa.period
,aaa."PayeeID"
,aaa."Reports_to" MANAGER
,aaa."Component" comp,
aaa."Current_YTD_Actual" cytd,
aaa."Current_YTD_Plan" cytp
from nbr_var_data aaa
where aaa."Comp_Plan_Name" not in ('MISC_COMP','GM_2017')
AND "Comp_Plan_Name" not in ('MISC_COMP')
AND "Comp_Plan_Name" not LIKE '%GM%'
and aaa.period = (select max(aaa.period) from Nbr_Var_Data)
))
)
where 1=1
group by period, rep_code, comp, bucket, manager )
group by period, rep_code, comp, manager )) group by period, manager, comp)
SELECT DISTINCT
dc.rep PID
,dc.period
,ee.PAYEE_NAM
,dc.comp
,Dc."GT99"
,Dc."90TO99"
,Dc."80TO89"
,Dc."70TO79"
,Dc."LT70"
,Dc."NA"
,Ee.Parent_Payee_Id REPORT_TO_PAYEE_ID
,Ee.Parent_Payee_Nam REPORT_TO_NAME
FROM (SELECT
--period ,
--empl_id ,
gg.payee_id ,
gg.payee_nam ,
--lvl ,
ff.parent_payee_id ,
ff.PARENT_PAYEE_NAM
--parent_lvl ,
--mnth_disp
FROM (SELECT DISTINCT
dd.period
,dd.PARENT_PAYEE_ID
,ee.PAYEE_NAM PARENT_PAYEE_NAM
from (
SELECT DISTINCT
PERIOD,
PARENT_PAYEE_ID
FROM FI_CHANNEL_HIER) dd
left join FI_CHANNEL_HIER ee
on dd.PARENT_PAYEE_ID = ee.PAYEE_ID
WHERE DD.PERIOD = (select max(DD.PERIOD) from FI_CHANNEL_HIER )) ff
LEFT JOIN FI_CHANNEL_HIER gg
ON ff.PARENT_PAYEE_ID = gg.PARENT_PAYEE_ID) ee,
NEW_REP_DATA dc
WHERE EE.PAYEE_ID = DC.Rep
AND dc.period = (select max(period) from NEW_REP_DATA)
;

oracle SQL procedure updating table

I need to update the the following columns in a table. males,females,infants and children using SQL procedure.from this column paxtype which has f,i,m,c.which is females,infants,males and children repectively.but am not able error ORA-00907: missing right parenthesis
update xxxx a set (a.INFANTS,a.MALES,a.CHILDREN,a.FEMALES)=
(SELECT b.PAXTYPE, COUNT (b.PAXTYPE) FROM xxxx b
(case ( count (b.PAXTYPE))
when ( count (b.PAXTYPE))='M'then 'a.males'
when ( count (b.PAXTYPE))='F' then 'a.females'
when ( count (b.PAXTYPE))='I' then 'a.infants'
when ( count (b.PAXTYPE))='C' then 'a.children'
END)
WHERE a.date_key = TO_CHAR (b.FLIGHTDATE, 'RRRRMMDD')
AND a.FLTNUM_KEY = TRIM (SUBSTR (b.flightnumber, 3))
AND a.origin = b.frm
AND a.destination = b.too
--and a.date_key=20170801
--and fightnumber = '100'
AND TRIM (a.cancelled) IS NULL
-- and rownum = 1
GROUP BY b.PAXTYPE;
)
It looks like you want a total count of each type, right? I think this is what you want to do.
update xxxx a set (a.INFANTS,a.MALES,a.CHILDREN,a.FEMALES)=
(SELECT
sum(case when b.PAXTYPE = 'I' then 1 else 0 end) as infants_count,
sum(case when b.PAXTYPE = 'M' then 1 else 0 end) as males_count,
sum(case when b.PAXTYPE = 'C' then 1 else 0 end) as children_count,
sum(case when b.PAXTYPE = 'F' then 1 else 0 end) as females_count
FROM xxxx b
WHERE a.date_key = TO_CHAR (b.FLIGHTDATE, 'RRRRMMDD')
AND a.FLTNUM_KEY = TRIM (SUBSTR (b.flightnumber, 3))
AND a.origin = b.frm
AND a.destination = b.too
--and a.date_key=20170801
--and fightnumber = '100'
AND TRIM (a.cancelled) IS NULL
-- and rownum = 1
GROUP BY b.PAXTYPE);

Alternatives to CASE in Oracle 8i [duplicate]

This question already has answers here:
Query works on Oracle 11g but fails on Oracle 8i
(2 answers)
Closed 9 years ago.
Thanks to the stackoverflow community I found out that this query is not supported in Oracle 8i because of the CASE WHEN.
select (case
when seqnum = 1 then
'1'
when seqnum = cnt then
'0'
end) as value1,
(case
when seqnum = 1 then
t.BEGIN_DT
when seqnum = cnt then
t.END_DT
end) as TIME1,
t4.UNIT1 || '.SUBBATCH_TRIGGER' TAG
from (select t.*,
row_number() over(partition by t.BATCH_ID, t.plant_unit, t3.ID2 order by t.BEGIN_DT) as seqnum,
count(*) over(partition by t.BATCH_ID, t.plant_unit, t3.ID2) as cnt
from SCH2.tb_pg_unit_stap t
join (select ID1,batch_id from SCH2.VW_BATCH) t2 on t.BATCH_ID = t2.BATCH_ID
join (select ID2,ID1 from SCH1.STEP) t3 on t3.ID1 = t2.ID1) t
join SCH2.TB_W_MACHINE t4 on t4.plant_unit = t.plant_unit
where (seqnum = 1
or seqnum = cnt) AND (t.BEGIN_DT > '01-jan-2013' AND t.BEGIN_DT < '01-feb-2013');
What are the alternatives for this query to run on Oracle 8i?
Thanks in advance!
You should try with decode(..., ..., ...)
select
decode(seqnum,
1 , '1',
cnt, '0'
) as value1,
decode(seqnum,
1 , t.BEGIN_DT,
cnt, t.END_DT
) as TIME1
...
here's the link to the documentation of decode.
However, as has been pointed out in a comment, the join construct (ansi joins) won't work in 8i either.
instead of (case when seqnum = 1 then '1' when seqnum = cnt then '0' end)
you could use decode(seqnum, 1, '1', decode(seqnum, cnt, '0'))
I hope you get the idea

How do I sum records by week using pl/sql?

I have a query in Oracle for a report that looks like this:
SELECT TRUNC (created_dt) created_dt
, COUNT ( * ) AllClaims
, SUM(CASE WHEN filmth_cd in ('T', 'C') THEN 1 ELSE 0 END ) CT
, SUM(CASE WHEN filmth_cd = 'W' THEN 1 ELSE 0 END ) Web
, SUM(CASE WHEN filmth_cd = 'I' THEN 1 ELSE 0 END ) Icon
FROM claims c
WHERE c.clsts_cd NOT IN ('IN', 'WD')
AND TRUNC (created_dt) between
to_date('1/1/2006', 'dd/mm/yyyy') AND
to_date('1/1/2100', 'dd/mm/yyyy')
GROUP BY TRUNC (created_dt)
ORDER BY TRUNC (created_dt) DESC;
It returns data like this:
Create_Dt AllClaims CT Web Icon
1/26/2011 675 356 285 34
1/25/2011 740 322 379 39
...
What I need is a result set that sums all of the daily values into a weekly value. I am pretty new to PL/SQL and not sure where to begin.
Something like
SELECT TRUNC (created_dt, 'IW') created_dt
, COUNT ( * ) AllClaims
, SUM(CASE WHEN filmth_cd in ('T', 'C') THEN 1 ELSE 0 END ) CT
, SUM(CASE WHEN filmth_cd = 'W' THEN 1 ELSE 0 END ) Web
, SUM(CASE WHEN filmth_cd = 'I' THEN 1 ELSE 0 END ) Icon
FROM claims c
WHERE c.clsts_cd NOT IN ('IN', 'WD')
AND TRUNC (created_dt) between
to_date('1/1/2006', 'dd/mm/yyyy') AND
to_date('1/1/2100', 'dd/mm/yyyy')
GROUP BY TRUNC (created_dt, 'IW')
ORDER BY TRUNC (created_dt, 'IW') DESC;
will aggregate the data based on the first day of the ISO week.
Here is a simple example that I quite often use:
SELECT
TO_CHAR(created_dt,'WW'),
max(created_dt),
COUNT(*)
from MY_TABLE
group by
TO_CHAR(created_dt,'WW');
The to_char(created_dt,'WW') create the groups, and the max(created_dt) displays the last day of the week. Use min(created_dt) if you want to display the first day of the week.

Resources