I am trying to create a CTE to use the same in Merge statement in Oracle, but facing error so please have a look and help me out, earlier we were using subquery instead CTE but to enhance the response time of query I am trying CTE so please suggest me another approach to enhance the response time of query. Curious to know whether oracle supports CTE and Merge statement together as I did in below code.
With TRANS_HIST
As
(Select
NUMERO_DE_CUENTA,
TRANS_DATETIME,
Lag(TRANS_DATETIME, 1)
over
(
ORDER BY NUMERO_DE_CUENTA,TRANS_DATETIME) lag_trans_datetime
FROM db_fraud_bpd.tbl_event_new_transaction_h
)
MERGE
INTO DB_FRAUD_BPD.TBL_RT_FEATURES_TEMP t1
USING
(
SELECT
RTTEMP.ACCOUNT_NUMBER,
RTTEMP.TRANS_DATETIME,
CASE WHEN STDDEV(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime) = 0 THEN NULL
WHEN ROUND(( ( (RTTEMP.TRANS_DATETIME - Max(TRANS_HIST.TRANS_DATETIME)) - Avg(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime)) / STDDEV(TRANS_HIST.TRANS_DATETIME -TRANS_HIST.lag_trans_datetime)),3) >999999999999999 THEN 999999999999999
WHEN ROUND(( ( (RTTEMP.TRANS_DATETIME - Max(TRANS_HIST.TRANS_DATETIME)) - Avg(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime)) / STDDEV(TRANS_HIST.TRANS_DATETIME -TRANS_HIST.lag_trans_datetime)),3) <-99999999999999 THEN -99999999999999
ELSE ROUND(( ( (RTTEMP.TRANS_DATETIME - Max(TRANS_HIST.TRANS_DATETIME)) - Avg(TRANS_HIST.TRANS_DATETIME - TRANS_HIST.lag_trans_datetime)) / STDDEV(TRANS_HIST.TRANS_DATETIME -TRANS_HIST.lag_trans_datetime)),3)
END AS TIME_DELTA_ZSCORE_PAST_90_DAYS
FROM TRANS_HIST
right outer join
db_fraud_bpd.tbl_rt_features_temp RTTEMP
ON Cast(RTTEMP.account_number AS INTEGER) = Cast(TRANS_HIST.NUMERO_DE_CUENTA AS INTEGER)
WHERE
(
TRANS_HIST.TRANS_DATETIME < RTTEMP.TRANS_DATETIME
AND TRANS_HIST.TRANS_DATETIME >= (RTTEMP.TRANS_DATETIME-90)
)
or TRANS_HIST.TRANS_DATETIME IS NULL
GROUP BY
RTTEMP.account_number,
RTTEMP.TRANS_DATETIME
)TEMP
ON (t1.TRANS_DATETIME=TEMP.TRANS_DATETIME AND t1.ACCOUNT_NUMBER=TEMP.ACCOUNT_NUMBER)
WHEN MATCHED
THEN UPDATE
SET t1.TIME_DELTA_ZSCORE_PAST_90_DAYS = TEMP.TIME_DELTA_ZSCORE_PAST_90_DAYS
You may use CTE in the merge statement, but in the rigth position in the merge subquery.
See example below
merge into tab
using (with t as (
select 1 id, 'x' x from dual union all
select 2 id, 'y' x from dual)
select * from t) b
on (tab.id = b.id)
when matched then
update set tab.x = b.x
when not matched then
insert (id, x)
values (b.id, b.x);
Don't use TRANS_HIST as a CTE, but as a subquery.
MERGE INTO DB_FRAUD_BPD.TBL_RT_FEATURES_TEMP t1
USING ( SELECT RTTEMP.ACCOUNT_NUMBER,
RTTEMP.TRANS_DATETIME,
CASE
WHEN STDDEV (
TRANS_HIST.TRANS_DATETIME
- TRANS_HIST.lag_trans_datetime) =
0
THEN
NULL
WHEN ROUND (
( ( ( RTTEMP.TRANS_DATETIME
- MAX (TRANS_HIST.TRANS_DATETIME))
- AVG (
TRANS_HIST.TRANS_DATETIME
- TRANS_HIST.lag_trans_datetime))
/ STDDEV (
TRANS_HIST.TRANS_DATETIME
- TRANS_HIST.lag_trans_datetime)),
3) >
999999999999999
THEN
999999999999999
WHEN ROUND (
( ( ( RTTEMP.TRANS_DATETIME
- MAX (TRANS_HIST.TRANS_DATETIME))
- AVG (
TRANS_HIST.TRANS_DATETIME
- TRANS_HIST.lag_trans_datetime))
/ STDDEV (
TRANS_HIST.TRANS_DATETIME
- TRANS_HIST.lag_trans_datetime)),
3) <
-99999999999999
THEN
-99999999999999
ELSE
ROUND (
( ( ( RTTEMP.TRANS_DATETIME
- MAX (TRANS_HIST.TRANS_DATETIME))
- AVG (
TRANS_HIST.TRANS_DATETIME
- TRANS_HIST.lag_trans_datetime))
/ STDDEV (
TRANS_HIST.TRANS_DATETIME
- TRANS_HIST.lag_trans_datetime)),
3)
END AS TIME_DELTA_ZSCORE_PAST_90_DAYS
FROM (SELECT NUMERO_DE_CUENTA,
TRANS_DATETIME,
LAG (TRANS_DATETIME, 1)
OVER (
ORDER BY NUMERO_DE_CUENTA, TRANS_DATETIME) lag_trans_datetime
FROM db_fraud_bpd.tbl_event_new_transaction_h)
TRANS_HIST
RIGHT OUTER JOIN db_fraud_bpd.tbl_rt_features_temp RTTEMP
ON CAST (RTTEMP.account_number AS INTEGER) =
CAST (TRANS_HIST.NUMERO_DE_CUENTA AS INTEGER)
WHERE ( TRANS_HIST.TRANS_DATETIME < RTTEMP.TRANS_DATETIME
AND TRANS_HIST.TRANS_DATETIME >=
(RTTEMP.TRANS_DATETIME - 90))
OR TRANS_HIST.TRANS_DATETIME IS NULL
GROUP BY RTTEMP.account_number, RTTEMP.TRANS_DATETIME) TEMP
ON ( t1.TRANS_DATETIME = TEMP.TRANS_DATETIME
AND t1.ACCOUNT_NUMBER = TEMP.ACCOUNT_NUMBER)
WHEN MATCHED
THEN
UPDATE SET
t1.TIME_DELTA_ZSCORE_PAST_90_DAYS = TEMP.TIME_DELTA_ZSCORE_PAST_90_DAYS
Related
I have the following SQL query :
SELECT
AVG(
nvl("PROP_TxMarge",0) * ((nvl("PROP_MtDemandeFin",0) - ( nvl("ENV_MontantInitial",0) - nvl("ENV_MontantDisponible",0) ) ) * nvl("POOLFIN_Pct",0))
)
FROM myTable
and this is the KPI syntax I am using :
KPIFormula := AVERAGEX('myTable',
[PROP_TxMarge] *
(
( [PROP_MtDemandeFin]
- ( [ENV_MontantInitial]
- [ENV_MontantDisponible] ))
* [POOLFIN_Pct]
)
)
I am having different results.
PROCEDURE DELETE_X1
IS
v_emp_unum VARCHAR2 (25);
BEGIN
/*FOR rec
IN (SELECT l2.*,
row_number ()
OVER (PARTITION BY case_uid,nvl(min_eff_date, eff_begin_date)
ORDER BY case_uid,nvl(min_eff_date, eff_begin_date))
rw,
ROWID rid
FROM (SELECT l1.*,
MIN (
CASE
WHEN eff_end_date = next_begin - 1
THEN
eff_begin_date
END)
OVER (PARTITION BY case_uid)
min_eff_date,
MAX (
CASE
WHEN previous_end <>
TO_DATE ('12/31/9999',
'mm/dd/yyyy')
AND previous_end + 1 = eff_begin_date
THEN
eff_end_date
END)
OVER (PARTITION BY case_uid)
max_end_date
FROM (SELECT GT.*,
LEAD (
EFF_begin_DATE)
OVER (PARTITION BY CASE_UID
ORDER BY EFF_BEGIN_DATE)
next_begin,
LAG (
EFF_end_DATE)
OVER (PARTITION BY CASE_UID
ORDER BY EFF_BEGIN_DATE)
previous_end
FROM TABLE_OUTPUT GT
WHERE SRC = 'ERICSSON' AND STATUS_CODE = 'X1') l1)
l2)*/
FOR rec
IN (SELECT l2.*,
ROW_NUMBER ()
OVER (PARTITION BY case_uid, min_eff_date, max_end_date
ORDER BY case_uid, min_eff_date, max_end_date)
rw,
ROWID rid
FROM (SELECT l1.*,
(MAX (
start_at)
OVER (
PARTITION BY case_uid
ORDER BY EFF_BEGIN_DATE
ROWS UNBOUNDED PRECEDING))
min_eff_date,
(MIN (
break_at)
OVER (
PARTITION BY case_uid
ORDER BY EFF_BEGIN_DATE
ROWS BETWEEN CURRENT ROW
AND UNBOUNDED FOLLOWING))
max_end_date
FROM (SELECT GT.*,
(CASE
WHEN LAG (
EFF_end_DATE)
OVER (
PARTITION BY CASE_UID
ORDER BY EFF_BEGIN_DATE) =
EFF_BEGIN_DATE
- 1
THEN
NULL
ELSE
EFF_BEGIN_DATE
END)
start_at,
(CASE
WHEN LEAD (
EFF_BEGIN_DATE)
OVER (
PARTITION BY case_uid
ORDER BY EFF_BEGIN_DATE) =
CASE
WHEN EFF_end_DATE <>
TO_DATE (
'12/31/9999',
'mm/dd/yyyy')
THEN
EFF_end_DATE
+ 1
ELSE
EFF_end_DATE
END
THEN
NULL
ELSE
EFF_end_DATE
END)
break_at
FROM TABLE_OUTPUT GT
WHERE SRC = 'ERICSSON' AND STATUS_CODE = 'X1') l1)
l2)
The part of code is commented out an re written.
commented out code output
OFF TIME 1/1/2017 1/7/2017 X1
OFF TIME 1/8/2017 2/1/2017 X1
New code output
OFF TIME 1/1/2017 2/1/2017 X1
NORMAL 2/2/2017 2/2/2017 AB
OFF TIME 2/20/2017
The LAG function is used to access data from a previous row.
The LEAD function is used to return data from rows further down the result set.
aggregate functions MIN , MAX
i am pretty confused with the flow of code.
I can't understand that code on the whole please explain the logic for the code
I have the following table with a single column
Z_NUM
--------
34545
345
656
32
42
...
I want to build a following dependence
i | SUM(Z_NUM)
----------------
2 | 40934
3 | 51244
4 | 54793
...
based on query
SELECT SUM(z_num) FROM table WHERE z_num < i;
The variable i is a parameter and should be incremented by 1.
How to implement this query in ORACLE?
If I were doing this in MYSQL, I would write something like
SELECT
#n := #n + 1 n,
SUM(z_num)
FROM table, (SELECT #n := 1) m
WHERE z_num < n;
But unfortunately it does not work in Oracle PL/SQL.
Use two subqueries:
one with connect by to generate numbers i from 2 to N
another dependend subquery to calculate a sum for each i
SELECT i,
( SELECT coalesce( sum(z_num), 0 )
FROM table1 WHERE z_num < i
) as myresult
FROM (
SELECT level+1 As i FROM dual
CONNECT BY LEVEL <= ( SELECT max(Z_NUM) FROM table1 )-1
)
ORDER BY i
Demo: http://sqlfiddle.com/#!4/c460c/5
use ROWNUM,
SELECT SUM(z_num)
FROM (SELECT z_num, rownum rown
FROM table)
WHERE z_num < rown;
OR
SELECT SUM(z_num)
FROM (SELECT z_num, rownum rown
FROM table)
WHERE rown < 10;
Try this:
SELECT i,
( SELECT coalesce( sum(z_num), 0 )
FROM Table_NUM WHERE ROWNUM <= i
) as SUM(Z_NUM)
FROM (
SELECT level+1 As i FROM dual
CONNECT BY LEVEL <= ( SELECT Max(ROWNUM) FROM Table_NUM )-1
)
ORDER BY i;
Result:
I SUM_RESULT
-----------------
2 34890
3 35546
4 35578
5 35620
It may be help you.
I have a following query and it takes 12 hours to execute in HUE. I would like to increase the performance of the query. Let me know what changes I can implement in the query to increase the performance in HUE environment
SELECT ordernum,
Min(distance) mindist,
Min(CASE
WHEN type_name = 'T'
OR ( type_name = 'I'
AND item LIKE '%D%' ) THEN distance
ELSE 9999999
END) min_t,
Min(CASE
WHEN type_name = 'A' THEN distance
ELSE 9999999
END) min_a
FROM (SELECT a.ordernum,
b.id,
b.type_name,
b.item,
Round(Least(Sqrt(Pow(b.sty-a.nrthng, 2)
+ Pow(b.stx-a.estng, 2)),
Sqrt(Pow(b.endy-a.nrthng, 2)
+ Pow(b.endx-a.estng, 2))))
distance
FROM temp_b a,
min_b1 b
WHERE ( ( b.stx BETWEEN ( a.estng - 1000 ) AND ( a.estng + 1000 )
AND b.sty BETWEEN ( a.nrthng - 1000 ) AND
( a.nthing + 1000 ) )
OR ( b.endx BETWEEN ( a.estng - 1000 ) AND ( a.esng + 1000 )
AND b.endy BETWEEN ( a.nrthng - 1000 ) AND
( a.nrthng + 1000 ) ) )) a
GROUP BY ordernum
My concers are about your query join condition.
As I see, you have tables a and b. Are there any key fields so tables could be matched? I mean, field f1 from the table a has the same meaning as field f2 from table b so they could be joined.
You could also create temporary table containing information from both tables to remove overhead for network communication and data transfer as I believe your hadoop cluster contains more than single node.
So, I have this query that's just making me go crazy. For some crazy reason, the query runs and brings the desired output on PLSQL Developer, but on SQL Developer it doesn't! As far as I know, the exact same query should work on both, not just one or the other. Not everybody at my team has PLSQL Dev, so it has to work on both. This query also shows different behaviour on my BI Application. Has anyone seen this crazy behaviour before?
Here's the query:
with t1 as (
SELECT
case when CLG_STATUS.NM_STATUS in ('1 - ATIVO','5 - BLOQUEADO','7 - AGUARDANDO AUTENTICAÇÃO') then 'LG Club Member'
else 'Non Member'
end membership,
Round(
Round(SUM(NVL(CASE WHEN CLG_VENDA.CD_TP_VENDA = 'D' THEN -1*CLG_VENDA.QTD_VENDA ELSE CLG_VENDA.QTD_VENDA END,0)), 1)
/
Count(distinct CLG_PARTICIPANTE.ID)
, 1) as average_sales ,
Round(
SUM(NVL(CASE WHEN CLG_VENDA.CD_TP_VENDA = 'D' THEN -1*CLG_VENDA.QTD_VENDA ELSE CLG_VENDA.QTD_VENDA END,0))
, 1) as sellout,
Count(distinct CLG_PARTICIPANTE.ID)
as "qty members"
FROM
CLG_VENDA_PONTO,
CLG_PARTICIPANTE,
CLG_STATUS,
CLG_VENDA,
CLG_CARGO CLG_CARGO_VENDA,
CLG_CANAL CLG_CANAL_VENDA,
CLG_REDE CLG_REDE_VENDA,
CLG_PRODUTO,
CLG_TP_MOVIMENTO,
DIM_PERIOD_DAY PERIOD_VENDA_DATA,
CLG_LOJA CLG_LOJA_VENDA
WHERE
( CLG_VENDA_PONTO.ID_VENDA=CLG_VENDA.ID(+) )
AND ( CLG_VENDA_PONTO.ID_PROD=CLG_PRODUTO.ID(+) )
AND ( CLG_VENDA_PONTO.ID_CARGO=CLG_CARGO_VENDA.ID )
AND ( CLG_LOJA_VENDA.ID=CLG_VENDA_PONTO.ID_LOJA )
AND ( CLG_REDE_VENDA.ID=CLG_LOJA_VENDA.ID_REDE )
AND ( CLG_CANAL_VENDA.ID=CLG_VENDA_PONTO.ID_CANAL )
AND ( CLG_PARTICIPANTE.ID_LOJA=CLG_LOJA_VENDA.ID )
AND ( CLG_LOJA_VENDA.ID_REDE=CLG_REDE_VENDA.ID )
AND ( CLG_PARTICIPANTE.ID=CLG_VENDA_PONTO.ID_PARTCPTE )
AND ( CLG_VENDA_PONTO.ID_TP_MOVIMENTO=CLG_TP_MOVIMENTO.ID )
AND ( CLG_STATUS.ID=CLG_PARTICIPANTE.ID_STATUS )
AND ( CLG_VENDA_PONTO.DATA_VENDA=PERIOD_VENDA_DATA.YYYYMMDD )
AND ( CLG_CARGO_VENDA.NM_CARGO = '5 - VENDEDOR' OR CLG_VENDA.ID_CARGO = 8 )
AND
(
CLG_PRODUTO.NM_PRODUTO NOT IN ( 'M4338 - FRETE','R39745 - FRETE SOBRE VENDAS' )
AND
CLG_TP_MOVIMENTO.NM_MOVIMENTO IN ( '1 - VENDA','3 - DEVOLUCAO' )
AND
CLG_REDE_VENDA.NM_REDE = '21540901 - RABELO'
AND
PERIOD_VENDA_DATA.YYYYMMDD_DATE BETWEEN to_date('01-01-2013', 'DD-MM-YYYY') AND to_date('31-12-2013', 'DD-MM-YYYY')
AND
CLG_CANAL_VENDA.NM_CANAL IN ('1 - VAREJO')
AND
CLG_PRODUTO.FG_MAPEADO IN ( 'SIM' )
)
GROUP BY
case when CLG_STATUS.NM_STATUS in ('1 - ATIVO','5 - BLOQUEADO','7 - AGUARDANDO AUTENTICAÇÃO') then 'LG Club Member'
else 'Non Member'
end
), t2 as (
SELECT
case when CLG_STATUS.NM_STATUS in ('1 - ATIVO','5 - BLOQUEADO','7 - AGUARDANDO AUTENTICAÇÃO') then 'LG Club Member'
else 'Non Member'
end membership,
Round(
Round(SUM(NVL(CASE WHEN CLG_VENDA.CD_TP_VENDA = 'D' THEN -1*CLG_VENDA.QTD_VENDA ELSE CLG_VENDA.QTD_VENDA END,0)), 1)
/
Count(distinct CLG_PARTICIPANTE.ID)
, 1) as average_sales ,
Round(
SUM(NVL(CASE WHEN CLG_VENDA.CD_TP_VENDA = 'D' THEN -1*CLG_VENDA.QTD_VENDA ELSE CLG_VENDA.QTD_VENDA END,0))
, 1) as sellout,
Count(distinct CLG_PARTICIPANTE.ID)
as "qty members"
FROM
CLG_VENDA_PONTO,
CLG_PARTICIPANTE,
CLG_STATUS,
CLG_VENDA,
CLG_CARGO CLG_CARGO_VENDA,
CLG_CANAL CLG_CANAL_VENDA,
CLG_REDE CLG_REDE_VENDA,
CLG_PRODUTO,
CLG_TP_MOVIMENTO,
DIM_PERIOD_DAY PERIOD_VENDA_DATA,
CLG_LOJA CLG_LOJA_VENDA
WHERE
( CLG_VENDA_PONTO.ID_VENDA=CLG_VENDA.ID(+) )
AND ( CLG_VENDA_PONTO.ID_PROD=CLG_PRODUTO.ID(+) )
AND ( CLG_VENDA_PONTO.ID_CARGO=CLG_CARGO_VENDA.ID )
AND ( CLG_LOJA_VENDA.ID=CLG_VENDA_PONTO.ID_LOJA )
AND ( CLG_REDE_VENDA.ID=CLG_LOJA_VENDA.ID_REDE )
AND ( CLG_CANAL_VENDA.ID=CLG_VENDA_PONTO.ID_CANAL )
AND ( CLG_PARTICIPANTE.ID_LOJA=CLG_LOJA_VENDA.ID )
AND ( CLG_LOJA_VENDA.ID_REDE=CLG_REDE_VENDA.ID )
AND ( CLG_PARTICIPANTE.ID=CLG_VENDA_PONTO.ID_PARTCPTE )
AND ( CLG_VENDA_PONTO.ID_TP_MOVIMENTO=CLG_TP_MOVIMENTO.ID )
AND ( CLG_STATUS.ID=CLG_PARTICIPANTE.ID_STATUS )
AND ( CLG_VENDA_PONTO.DATA_VENDA=PERIOD_VENDA_DATA.YYYYMMDD )
AND ( CLG_CARGO_VENDA.NM_CARGO = '5 - VENDEDOR' OR CLG_VENDA.ID_CARGO = 8 )
AND
(
CLG_PRODUTO.NM_PRODUTO NOT IN ( 'M4338 - FRETE','R39745 - FRETE SOBRE VENDAS' )
AND
CLG_TP_MOVIMENTO.NM_MOVIMENTO IN ( '1 - VENDA','3 - DEVOLUCAO' )
AND
CLG_REDE_VENDA.NM_REDE = '21540901 - RABELO'
AND
PERIOD_VENDA_DATA.YYYYMMDD_DATE BETWEEN add_months(to_date('01-01-2013', 'DD-MM-YYYY'), -12) AND add_months(to_date('31-12-2013', 'DD-MM-YYYY'), -12)
AND
CLG_CANAL_VENDA.NM_CANAL IN ('1 - VAREJO')
AND
CLG_PRODUTO.FG_MAPEADO IN ( 'SIM' )
)
GROUP BY
case when CLG_STATUS.NM_STATUS in ('1 - ATIVO','5 - BLOQUEADO','7 - AGUARDANDO AUTENTICAÇÃO') then 'LG Club Member'
else 'Non Member'
end
)
select t1.*, coalesce((t1.average_sales - t2.average_sales) / t2.average_sales, 0) as variation
from t1 join t2 on t1.membership = t2.membership
On SQL Developer it displays this:
ORA-00928: missing SELECT keyword
00928. 00000 - "missing SELECT keyword"
I'm totally at a loss here. How can a query parse at one tool and not the other ? I tried searching around the net but to no avail.
Thanks in advance!
It might be the line,
/
SQL Plus uses / by itself to mark the end of a sql query, and SQL Developer most likely follows. However, the preceding whitespace may change the meaning, so this may not be the problem.
To test this hypothesis move the / to the preceding line. Change
Round(SUM(NVL(CASE WHEN CLG_VENDA.CD_TP_VENDA = 'D' THEN -1*CLG_VENDA.QTD_VENDA ELSE CLG_VENDA.QTD_VENDA END,0)), 1)
/
Count(distinct CLG_PARTICIPANTE.ID)
To
Round(SUM(NVL(CASE WHEN CLG_VENDA.CD_TP_VENDA = 'D' THEN -1*CLG_VENDA.QTD_VENDA ELSE CLG_VENDA.QTD_VENDA END,0)), 1) /
Count(distinct CLG_PARTICIPANTE.ID)
If that is the problem, then it is a matter of reformatting to something that works for you that doesn't leave / on a line by itself.