Subprogram or cursor '' reference is out of scope - oracle

Tell me how I can refer to the column when processing the current table. I need to do calculations with already calculated fields, referring to a table field through a pseudonym does not help, perhaps I am missing something else, but I will be glad if someone points out my stupidity to me. I don't see a solution in a simple place :(
Many thanks!
The problem lies in this place PLS-00225: subprogram or cursor 'F' reference is out of scope:
then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
Body pck:
create or replace package body dma.fill_f101_round_f is
procedure Log
( i_message in varchar2
)
is
begin
dma.logger.writeLog('[' || c_MartName || '] ' || i_message);
end;
----------------------------------------------------------------------------------------------------
----------------------------------------------------------------------------------------------------
procedure fill
( i_OnDate in date
)
is
begin
Log( '[BEGIN] fill(i_OnDate => date '''
|| to_char(i_OnDate, 'yyyy-mm-dd')
|| ''');'
);
Log( 'delete on_date = '
|| to_char(i_OnDate, 'yyyy-mm-dd')
);
delete
from dma.DM_F101_ROUND_F f
where trunc(i_OnDate, 'mm') = from_date
and last_day(i_OnDate) = to_date;
Log('insert');
insert
into dma.dm_f101_round_f f
( from_date
, to_date
, chapter
, ledger_account
, characteristic
, balance_in_rub
, balance_in_val
, balance_in_total
, turn_deb_rub
, turn_deb_val
, turn_deb_total
, turn_cre_rub
, turn_cre_val
, turn_cre_total
, balance_out_rub
, balance_out_val
, balance_out_total
)
select trunc(i_OnDate, 'mm') as from_date,
last_day(i_OnDate) as to_date,
s.chapter as chapter,
substr(acc_d.account_number, 1, 5) as ledger_account,
acc_d.char_type as characteristic,
-- RUB balance
sum( case
when cur.currency_code in ('643', '810')
then b.balance_out
else 0
end
) as balance_in_rub,
-- VAL balance converted to rub
sum( case
when cur.currency_code not in ('643', '810')
then b.balance_out * exch_r.reduced_cource
else 0
end
) as balance_in_val,
-- Total: RUB balance + VAL converted to rub
sum( case
when cur.currency_code in ('643', '810')
then b.balance_out
else b.balance_out * exch_r.reduced_cource
end
) as balance_in_total ,
-- RUB debet turnover
sum(case
when cur.currency_code in ('643', '810')
then at.debet_amount_rub
else 0
end
) as turn_deb_rub,
-- VAL debet turnover converted
sum(case
when cur.currency_code not in ('643', '810')
then at.debet_amount_rub
else 0
end
) as turn_deb_val,
-- SUM = RUB debet turnover + VAL debet turnover converted
sum(at.debet_amount_rub) as turn_deb_total,
-- RUB credit turnover
sum(case
when cur.currency_code in ('643', '810')
then at.credit_amount_rub
else 0
end
) as turn_cre_rub,
-- VAL credit turnover converted
sum(case
when cur.currency_code not in ('643', '810')
then at.credit_amount_rub
else 0
end
) as turn_cre_val,
-- SUM = RUB credit turnover + VAL credit turnover converted
sum(at.credit_amount_rub) as turn_cre_total,
sum( case
when cur.currency_code in ('643','810') and acc_d.char_type = 'A'
then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
when cur.currency_code in ('643','810') and acc_d.char_type = 'P'
then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
else 0
end
) as balance_out_rub,
sum( case
when cur.currency_code not in ('643', '810') and acc_d.char_type = 'A'
then f.balance_in_val - f.turn_cre_val + f.turn_deb_val
when cur.currency_code not in ('643', '810') and acc_d.char_type = 'P'
then f.balance_in_val + f.turn_cre_val - f.turn_deb_val
else 0
end
) as balance_out_val,
sum (f.balance_out_val + f.balance_out_rub) as balance_out_total
from ds.md_ledger_account_s s
join ds.md_account_d acc_d
on substr(acc_d.account_number, 1, 5) = s.ledger_account
join ds.md_currency_d cur
on cur.currency_rk = acc_d.currency_rk
left
join ds.ft_balance_f b
on b.account_rk = acc_d.account_rk
and b.on_date = trunc(i_OnDate, 'mm') - 1
left
join ds.md_exchange_rate_d exch_r
on exch_r.currency_rk = acc_d.currency_rk
and i_OnDate between exch_r.data_actual_date and exch_r.data_actual_end_date
left
join dma.dm_account_turnover_f at
on at.account_rk = acc_d.account_rk
and at.on_date between trunc(i_OnDate, 'mm') and last_day(i_Ondate)
where i_OnDate between s.start_date and s.end_date
and i_OnDate between acc_d.data_actual_date and acc_d.data_actual_end_date
and i_OnDate between cur.data_actual_date and cur.data_actual_end_date
group by s.chapter,
substr(acc_d.account_number, 1, 5),
acc_d.char_type;
Log('[END] inserted ' || to_char(sql%rowcount) || ' rows.');
commit;
end;
----------------------------------------------------------------------------------------------------
end fill_f101_round_f;
/ ```

This is f:
into dma.dm_f101_round_f f
^
here it is
f.balance_in_rub is this:
-- RUB balance
sum( case
when cur.currency_code in ('643', '810')
then b.balance_out
else 0
end
) as balance_in_rub,
--------------
here it is
You can't reference a column that's being inserted simply by naming it; it is unknown in this context. If you want to perform some calculations, you'll have to do that with the "source" itself, i.e.
then f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
would become
then
sum(case
when cur.currency_code in ('643', '810')
then b.balance_out
else 0
end
) -
sum(case
when cur.currency_code in ('643', '810')
then at.credit_amount_rub
else 0
end
) +
sum(case
when cur.currency_code in ('643', '810')
then at.debet_amount_rub
else 0
end
)
i.e. you'd re-use all that code. Not too pretty, I'm afraid.
Another option is to do insert first, update next as you'd then just
update dm_f101_round_f f set
f.balance_out_rub = f.balance_in_rub - f.turn_cre_rub + f.turn_deb_rub
where ...

Related

Oracle store procedure to retrieve dates ny passing column name as parameter

The below procedure returns thousands of lines by passing start date and end date. Added to that i need to add one parameter which should apply the start date and end date on different columns such as created date, planned date and end date which are available in result set.
For instance if i pass the value as (created date,'31/10/2020 00:00:00','01/11/2020 00:00:00'), the filter should be applied on created date column, if i pass (end,'31/10/2020 00:00:00','01/11/2020 00:00:00'), the filter should be applied on end date column.
How can i achieve this ?
create or replace PROCEDURE CVP_TEST(STARTDATE VARCHAR, ENDDATE VARCHAR) AS
st_dt TIMESTAMP := TO_TIMESTAMP(STARTDATE, 'dd/mm/yyyy hh24:mi:ss');
end_dt TIMESTAMP := TO_TIMESTAMP(ENDDATE, 'dd/mm/yyyy hh24:mi:ss');
cursor cur1(start_time timestamp, end_time timestamp)
is
SELECT
A.LGST_GRP_CD ,
(case when A.FRST_SHPG_LOC_CD like 'D%' then A.FRST_SHPG_LOC_CD
when (A.FRST_SHPG_LOC_CD not like 'D%' and A.DMCL_CD is not null and length(dmcl_t.shpgloc_cd) <= 4) then dmcl_t.shpgloc_cd
--when (A.FRST_SHPG_LOC_CD not like 'D%' and A.DMCL_CD is null and length(dom_carrier.shpgloc_cd) <= 4) then dom_carrier.shpgloc_cd
else A.FRST_SHPG_LOC_CD end) AS Dispatch_DC,
--ba_tmextra.FUN_GET_INT_DC(A.LD_LEG_ID) AS INT_DC,
'XXX' AS INT_DC,
A.CUR_OPTLSTAT_ID,
--V.CUR_STAT_ID,
A.TRIP_ID AS TRIP_ID,
A.LD_LEG_ID AS LOAD_ID,
A.CARR_CD AS CARRIER_ID,
A.SRVC_CD AS SERVICE_ID,
A.EQMT_TYP AS EQMT_TYP,
A.STRD_DTT AS START_DATE,
A.END_DTT AS END_DTT,
A.CRTD_DTT AS CRTD_DTT,
A.TRCTR_NUM as TRCTR_NUM,
A.DRVR as DRVR,
A.TRLR_NUM,
A.FRST_SHPG_LOC_CD,
A.LAST_SHPG_LOC_CD,
A.NUM_STOP as NUM_STOP,
--BA_TMEXTRA.FUN_GET_STOP_LOC(A.LD_LEG_ID, 0) STOP_LIST,
'XXX' AS STOP_LIST,
LD_MMO.PRTB_CTNT AS LD_COMMENTS,
A.MILE_DIST AS MILE_DIST,
A.TOT_SCLD_WGT AS TOTAL_WEIGHT,
A.ELPD_HRS,
CM.chrg_extl_code2 as chrg_extl_code2,
(case when CM.chrg_extl_code2 = 'HAUL' then C.CHRG_CD else null end) as Haul_Charge_ID,
(case when CM.chrg_extl_code2 = 'HAUL' then C.CHGD_UNIT_RATE else null end) as Planned_Rate,
(case when CM.chrg_extl_code2 = 'FUEL' then C.CHGD_UNIT_RATE else null end) as Fuel_Planned_Rate,
(case when CM.chrg_extl_code2 = 'FUEL' then C.CHRG_CD else null end) as Fuel_Surcharge_Type_ID,
(case when CM.chrg_extl_code2 = 'STOP' then C.CHRG_CD else null end) as Stop_Off_Charge_ID,
--C.CHRG_CD AS CHRG_CD,
--C.CHGD_UNIT_RATE AS PLANNED_RATE,
NVL(C.MNLY_OVRD_DLR,0) as CHRG_GRP_AMT
FROM JDATM_PROD.LD_LEG_T A, JDATM_PROD.CHRG_DETL_T C, JDATM_PROD.IA_DIST_MSTRCHRG CM,
JDATM_PROD.DMCL_T,
--DMCL_T DOM_CARRIER,
--VCHR_AP_T V,
JDATM_PROD.MMO_T LD_MMO
WHERE 1=1
AND A.LD_LEG_ID = C.LD_LEG_ID
AND C.CHRG_CD = CM.CHRG_CODE
AND C.CHRGDETL_TYP_ENU = 1
AND C.CHRG_LVL_ENU != 7
AND A.DMCL_CD=DMCL_T.DMCL_CD(+)
--AND DOM_CARRIER.CARR_CD(+)=A.CARR_CD
--AND V.VCHR_NUM (+) = C.VCHR_NUM_AP
--AND V.CUR_STAT_ID (+) != 825
and A.mmo_id = ld_mmo.mmo_id (+)
AND A.TRIP_ID IS NULL
--AND A.LD_LEG_ID = 1001038103
AND A.RATG_VLID_YN = 'T'
AND A.STRD_DTT BETWEEN start_time and end_time;
read_value cur1%ROWTYPE;
BEGIN
--dbms_output.put_line('Accepted:' || STARTDATE || ', ' || ENDDATE);
--dbms_output.put_line('Assigned:' || st_dt || ', ' || end_dt);
END;
You can use the OR condition as follows:
AND (
(P_IN_COLUMN_NAME = 'created date' AND A.CREATED_DTT BETWEEN start_time and end_time)
OR
(P_IN_COLUMN_NAME = 'planned date' AND A.PLANNED_DTT BETWEEN start_time and end_time )
)

How To - SELECT additional rows based on fiscal begin date and end date

I need to split each row into x rows based on begin_dt and end_dt of the fiscal year.
Can this be done in oracle ?
Script I used
As you see, they are not dynamic. A lot of copy and paste for each pp column and I need to know my data in advance.
If I don't have any option, how do I move data in the column and put in the row instead?
Will pivot or unpivot fix the issue?
This is the base table
ANIMAL BEGIN_DT END_DT
-------- --------- ----------
dog 9/1/2017 6/30/2018
pig 7/15/1999 5/28/2001
cat 3/1/2018 1/27/2020
This is what I have so far
ANIMAL ORG_BEGIN_DT ORG_END_DT BP1 B1 E1 BP2 B2 E2 BP3 B3 E3
---- ------------ ------------ ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
dog 09/01/2017 09/01/2017 FY2018 09/01/2017 06/30/2018
pig 07/15/1999 07/15/1999 FY2000 07/15/1999 06/30/2000 FY2001 07/01/2000 05/28/2001
cat 03/01/2018 03/01/2018 FY2018 03/01/2018 06/30/2018 FY2019 07/01/2018 06/30/2019 FY2019 07/01/2019 01/27/2020
SET LINESIZE 32000;
column animal format a6
column ORG_BEGIN_DT format a12
column ORG_END_DT format a12
column BP1 format a10
column BP2 format a10
column BP3 format a10
column B1,B2,B3 format a17
column E1,E2,E3 format a17
CREATE TABLE SRCTBL (ANIMAL VARCHAR2(25) NOT NULL,
PERIOD_ID VARCHAR2(12) NOT NULL,
BEGIN_DT DATE,
END_DT DATE)
/
insert into SRCTBL values ( 'dog', ' ', to_date('9/1/2017','MM/DD/YYYY') , to_date('6/30/2018','MM/DD/YYYY' ));
insert into SRCTBL values ( 'pig', ' ', to_date('7/15/1999','MM/DD/YYYY'), to_date('5/28/2001','MM/DD/YYYY' ));
insert into SRCTBL values ( 'cat', ' ', to_date('3/1/2018','MM/DD/YYYY') , to_date('1/27/2020','MM/DD/YYYY' ));
commit;
with awrd as (select * from SRCTBL )
, pr as (select w.animal
, extract (month from w.begin_dt) begin_mon
, extract (month from w.end_dt) end_mon
, round(MONTHS_BETWEEN (w.end_dt ,w.begin_dt)) mth_dur
, round((w.end_dt - w.begin_dt)/365, 2) yr_dur
, case when extract ( month from w.begin_dt ) in (7,8,9,10,11,12)
then extract ( year from w.begin_dt ) + 1
else extract ( year from w.begin_dt ) end begin_yr
, case when extract ( month from w.end_dt ) in (7,8,9,10,11,12)
then extract ( year from w.end_dt ) + 1
else extract ( year from w.end_dt ) end AS end_yr
from SRCTBL w )
, calc as ( select pr.animal, begin_mon, end_mon , mth_dur , yr_dur ,begin_yr, end_yr from pr)
, pp1 as ( select calc.animal
, 'GFY-' || calc.begin_yr Budget_Period
, awrd.begin_dt
, case when calc.begin_mon >= 7 and calc.begin_yr = calc.end_yr and calc.end_mon > 6 then awrd.end_dt
when calc.begin_mon >= 7 and calc.begin_yr = calc.end_yr and calc.end_mon < 7 then awrd.end_dt
when calc.begin_mon >= 7 and calc.begin_yr <> calc.end_yr and calc.end_mon <= 7 then LAST_DAY ('30-JUN-'|| calc.begin_yr )
when calc.begin_mon >= 7 and calc.begin_yr <> calc.end_yr and calc.end_mon > 7 then LAST_DAY ('30-JUN-'|| calc.begin_yr )
when calc.begin_mon < 7 and awrd.end_dt > LAST_DAY ('30-JUN-'|| calc.begin_yr) then LAST_DAY ('30-JUN-'|| calc.begin_yr )
else awrd.end_dt end end_dt
from calc, awrd
where calc.animal= awrd.animal)
, pp2 as ( select pp1.animal
, case when awrd.end_dt = pp1.end_dt then NULL else 'GFY-' || to_char(to_number (calc.begin_yr) + 1) end Budget_Period
, case when awrd.end_dt = pp1.end_dt then NULL else pp1.end_dt + 1 end begin_dt
, case when awrd.end_dt = pp1.end_dt then NULL
when awrd.end_dt < LAST_DAY ('30-JUN-'|| to_char(to_number (calc.begin_yr) + 1)) then awrd.end_dt
else LAST_DAY ('30-JUN-'|| to_char(to_number (calc.begin_yr) + 1)) end end_dt
from pp1 , calc , awrd
where calc.animal = awrd.animal
and calc.animal = pp1.animal )
, pp3 as ( select pp2.animal
, case when awrd.end_dt = pp2.end_dt then NULL
when pp2.end_dt is null then NULL
else 'GFY-' || to_char(to_number (calc.begin_yr) + 1) end Budget_Period
, case when awrd.end_dt = pp2.end_dt then NULL else pp2.end_dt + 1 end begin_dt
, case when awrd.end_dt = pp2.end_dt then NULL
when pp2.end_dt is null then NULL
when awrd.end_dt < LAST_DAY ('30-JUN-'|| to_char(to_number (calc.begin_yr) + 2)) then awrd.end_dt
else LAST_DAY ('30-JUN-'|| to_char(to_number (calc.begin_yr) + 2)) end end_dt
from pp2 , calc , awrd
where calc.animal = awrd.animal
and calc.animal = pp2.animal )
select a.animal TYPE
, a.begin_dt, a.end_dt
, pp1.budget_period, pp1.begin_dt, pp1.end_dt
, pp2.budget_period, pp2.begin_dt, pp2.end_dt
, pp3.budget_period, pp3.begin_dt, pp3.end_dt
from awrd A , pp1, pp2, pp3
where a.animal = pp1.animal
and a.animal = pp2.animal
and a.animal = pp3.animal;
This is the result I need
ANIMAL FISCAL_YEAR BEGIN_DT END_DT
-------- --------- ---------- ----------
dog FY2018 9/1/2017 6/30/2018
pig FY2000 7/15/1999 6/30/2000
pig FY2001 7/1/2000 5/28/2001
cat FY2018 3/1/2018 6/30/2018
cat FY2019 7/1/2018 6/30/2019
cat FY2020 7/1/2019 1/27/2020
Thank you #Hanna, it works.
select s.animal , 'GFY-' || extract ( year from fy.end_dt ) period_id
, case when s.begin_dt > fy.begin_dt then s.begin_dt else fy.begin_dt end begin_dt
, case when s.end_dt > fy.end_dt then fy.end_dt else s.end_dt end end_dt
from srctbl s, fiscal_years fy
where (( s.begin_dt between fy.begin_dt and fy.end_dt )
or ( s.end_dt between fy.begin_dt and fy.end_dt )
or ( s.begin_dt < fy.begin_dt and s.end_dt > fy.end_dt ))
order by 1,2;```
This is how I would do it. Basically, you need a row source for your fiscal years. Here, I'm doing that on the fly inside a Common Table Expression. (I've made the range of fiscal years a bit larger than necessary because I'm too lazy to do the math.) You could also create an explicit table.
with fiscal_years as (
select 'FY' || to_char(1995+level) as fy_name,
to_date( '07/01/' || to_char(1995+level-1), 'MM/DD/YYYY' ) as begin_dt,
to_date( '06/30/' || to_char(1995+level), 'MM/DD/YYYY' ) as end_dt
from dual
connect by level <= 40
)
select s.animal, fy.begin_dt, fy.end_dt
from srctbl s
inner join fiscal_years fy
on ( s.begin_dt between fy.begin_dt and fy.end_dt )
or ( s.end_dt between fy.begin_dt and fy.end_dt )
or ( s.begin_dt < fy.begin_dt and s.end_dt > fy.end_dt )
SQL Fiddle

ORA-01652:unable to extend temp segment by 128 in table space TEMP

I tried executing the below query but getting error "ORA-01652: unable to extend temp segment by 128 in tablespace TEMP" in Prod where as it is succefully executing in lower environments.
Other than increasing the TEMP table space , can someone please suggest an alternative?
Thank you for your help.
INSERT /*+ APPEND */ INTO PFE_GP.CONT_DATA(SC_ID,
ID,
PRD,
CONT,
QTY,
PRICE,
PRICE2,
PRICE3,
TOTAL_SALES,
TOTAL_DISCOUNT)
SELECT A.*,
SUM (SALES) OVER (PARTITION BY CONT) AS TOTAL_SALES,
SUM (DISCOUNT) OVER (PARTITION BY CONT) AS TOTAL_DISCOUNT
FROM (
SELECT /*+ FULL(T) PARALLEL(T 8)*/ D.SC_ID,
T.ID,
T.PRD,
R1.CONT,
T.QTY,
T.PRICE,
B.PRICE2,
B.PRICE3,
T.PRICE*T.QTY AS SALES,
T.DISC DISCOUNT
FROM TC T
, BNDL_DFN X
, SOURCE_DATES D
, XREF R1
, PRICE B,
WC_PR W
WHERE D.SOURCE_TABLE = 'CBK'
AND UPPER (X.LEVEL) = 'CONTRACT'
AND X.OFFSET >= 0
AND D.AS_OF_DATE BETWEEN T.EFFECTIVE_DATE AND T.EXPIRATION_DATE
AND TRUNC (T.INV_DATE) BETWEEN X.EFF_DATE AND X.EXP_DATE
AND TRUNC (T.INV_DATE) BETWEEN R1.EFFECTIVE_DATE AND R1.EXPIRATION_DATE
AND T.CON = X.CONT
AND T.PRD = X.PRD
AND T.PRD = W.PRD
AND TRUNC (T.INV_DATE) BETWEEN W.EFFECTIVE_START_DATE and W.EFFECTIVE_END_DATE
AND UPPER(R1.PURP) = 'OTHER'
AND (T.CONT = R1.CONT OR T.PR_GROUP = R1.CONT)
AND T.CONT = B.CONT
AND T.PRD = B.PRD
AND TRUNC(T.INV_DATE) BETWEEN B.DT_START AND B.DT_END
UNION
SELECT /*+ FULL(T) PARALLEL(T 8)*/ D.SC_ID,
T.ID,
T.PRD,
R1.CONT,
T.QTY,
T.PRICE,
B.PRICE2,
B.PRICE3,
T.PRICE*T.QTY AS SALES,
0 DISCOUNT
FROM TC T
, BNDL_DFN X
, SOURCE_DATES D
, XREF R1
, PRICE B,
WC_PR W
WHERE D.SOURCE_TABLE = 'CBK'
AND UPPER (X.LEVEL) = 'CONTRACT'
AND X.OFFSET >= 0
AND D.AS_OF_DATE BETWEEN T.EFFECTIVE_DATE AND T.EXPIRATION_DATE
AND TRUNC (T.INV_DATE) BETWEEN X.EFF_DATE AND X.EXP_DATE
AND TRUNC (T.INV_DATE) BETWEEN R1.EFFECTIVE_DATE AND R1.EXPIRATION_DATE
AND T.PR_GROUP = X.CONT
AND T.PRD = X.PRD
AND T.PRD = W.PRD
AND TRUNC (T.INV_DATE) BETWEEN W.EFFECTIVE_START_DATE and W.EFFECTIVE_END_DATE
AND UPPER(R1.PURP) = 'OTHER'
AND (T.CONT = R1.XREF OR T.PR_GROUP = R1.XREF)
AND T.CONT = B.CONT
AND T.PRD = B.PRD
AND TRUNC(T.INV_DATE) BETWEEN B.DT_START AND B.DT_END
AND T.CUST = TO_CHAR (X.TRAD_CUST)
AND (T.PRICE_GROUP = R1.XREF OR T.CONTRACT = R1.XREF)
) a;
COMMIT;
Use a temporary table to execute both halves of your union separately.
INSERT /*+ APPEND */
INTO tmp_cont_data
( sc_id
, id
, prd
, cont
, qty
, price
, price2
, price3
, total_sales
, total_discount )
SELECT /*+ FULL(T) PARALLEL(T 8)*/
d.sc_id
, t.id
, t.prd
, r1.cont
, t.qty
, t.price
, b.price2
, b.price3
, t.price * t.qty AS sales
, t.disc discount
FROM tc t
, bndl_dfn x
, source_dates d
, xref r1
, price b
, wc_pr w
WHERE d.source_table = 'CBK'
AND UPPER( x.LEVEL ) = 'CONTRACT'
AND x.offset >= 0
AND d.as_of_date BETWEEN t.effective_date AND t.expiration_date
AND TRUNC( t.inv_date ) BETWEEN x.eff_date AND x.exp_date
AND TRUNC( t.inv_date ) BETWEEN r1.effective_date AND r1.expiration_date
AND t.con = x.cont
AND t.prd = x.prd
AND t.prd = w.prd
AND TRUNC( t.inv_date ) BETWEEN w.effective_start_date AND w.effective_end_date
AND UPPER( r1.purp ) = 'OTHER'
AND ( t.cont = r1.cont
OR t.pr_group = r1.cont )
AND t.cont = b.cont
AND t.prd = b.prd
AND TRUNC( t.inv_date ) BETWEEN b.dt_start AND b.dt_end;
INSERT /*+ APPEND */
INTO tmp_cont_data
( sc_id
, id
, prd
, cont
, qty
, price
, price2
, price3
, total_sales
, total_discount )
SELECT /*+ FULL(T) PARALLEL(T 8)*/
d.sc_id
, t.id
, t.prd
, r1.cont
, t.qty
, t.price
, b.price2
, b.price3
, t.price * t.qty AS sales
, 0 discount
FROM tc t
, bndl_dfn x
, source_dates d
, xref r1
, price b
, wc_pr w
WHERE d.source_table = 'CBK'
AND UPPER( x.LEVEL ) = 'CONTRACT'
AND x.offset >= 0
AND d.as_of_date BETWEEN t.effective_date AND t.expiration_date
AND TRUNC( t.inv_date ) BETWEEN x.eff_date AND x.exp_date
AND TRUNC( t.inv_date ) BETWEEN r1.effective_date AND r1.expiration_date
AND t.pr_group = x.cont
AND t.prd = x.prd
AND t.prd = w.prd
AND TRUNC( t.inv_date ) BETWEEN w.effective_start_date AND w.effective_end_date
AND UPPER( r1.purp ) = 'OTHER'
AND ( t.cont = r1.xref
OR t.pr_group = r1.xref )
AND t.cont = b.cont
AND t.prd = b.prd
AND TRUNC( t.inv_date ) BETWEEN b.dt_start AND b.dt_end
AND t.cust = TO_CHAR( x.trad_cust )
AND ( t.price_group = r1.xref
OR t.contract = r1.xref );
INSERT /*+ APPEND */
INTO pfe_gp.cont_data
(
sc_id
, id
, prd
, cont
, qty
, price
, price2
, price3
, total_sales
, total_discount
)
SELECT a.*
, SUM( sales ) OVER (PARTITION BY cont) AS total_sales
, SUM( discount ) OVER (PARTITION BY cont) AS total_discount
FROM tmp_cont_data a;
It takes 3 statements instead of one, but should improve performace.
Look here for TT details: How do you create a temporary table in an Oracle database?

Plsql Program using control statements

I have a table like "Emp_Info", For the below output i have used "two" SELECT Statements, I want work that using ONE SELECT STATEMENT.
select count(*) into cnt
from emp_info t
where upper(trim(t.email)) = upper(trim(field1value))
and t.company_id = companyId;
select
(case when cnt1 > 0 then 'YES' else 'NO' end) into val_acc
from (
select count(*) cnt1 from
emp_info t
where upper(trim(t.email)) = upper(trim(field1value))
and (t.account_expiry_dt is null or t.account_expiry_dt >= sysdate)
and t.company_id = companyId
);
if cnt = 0 then
raise_application_error(-20002, 'User does not exist');
elsif cnt > 1 then
raise_application_error(-20003, 'Duplicate records found');
elsif val_acc = 'NO' then
raise_application_error(-20004, 'Account has expired');
else
/* some logic */
end if;
end;
may be this help you
select count(*),
CASE WHEN
sum( CASE when t.account_expiry_dt is null or t.account_expiry_dt >= sysdate then 1 else 0 end) > 0 then 'YES'
else 'NO'
END
into cnt, val_acc
from emp_info t
where upper(trim(t.email)) = upper(trim(field1value))
and t.company_id = companyId;
simple demo:
with emp_info(login,username) as (select 'test', 'test' from dual union
select 'TEst', 'TEst' from dual )
select count(*) emp_count,
CASE when sum( CASE WHEN login like '%st%' then 1 else 0 end) > 0 then 'Y' else 'N' end emp_flag,
sum( CASE WHEN login like '%st%' then 1 else 0 end) emp_flag_count,
CASE when sum( CASE WHEN login like '%te%' then 1 else 0 end) > 0 then 'Y' else 'N' end emp_flag1,
sum( CASE WHEN login like '%te%' then 1 else 0 end) emp_flag_count1,
CASE when sum( CASE WHEN login like '%TE%' then 1 else 0 end) > 0 then 'Y' else 'N' end emp_flag2,
sum( CASE WHEN login like '%TE%' then 1 else 0 end) emp_flag_count2
from emp_info
answer if it helped you

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