I've got this query in Oracle 11g [working fine]:
select (case
when seqnum = 1 then
t.DPR_N
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 timestamp,
t2.APP_NAAM || '.SUBBATCH_TRIGGER' TAGNAME1
from (select t.*,t6.*,
row_number() over(partition by t.BATCH_ID, t.PLANT_UNIT,t6.DPR_ID order by t.BEGIN_DT) as seqnum,
count(*) over(partition by t.BATCH_ID, t.PLANT_UNIT,t6.DPR_ID) as cnt
FROM tb_unit_step t
INNER JOIN tb_equipment t2
ON t2.PLANT_UNIT = t.PLANT_UNIT
INNER JOIN tb_rs3 t3
ON t.BATCH_ID = t3.BATCH_ID
INNER JOIN tb_cpm t9
ON t9.BACPM_ID = t3.BACPM_ID
INNER JOIN tb_step t4
ON (t9.BV_ID = t4.BV_ID
AND t.STAP_NR1 = t4.STAP_NR1
AND t.STAP_NR2 = t4.STAP_NR2)
INNER JOIN tb_bv t5
ON t5.BV_ID = t9.BV_ID
INNER JOIN tb_bv_process t6
ON t9.BV_ID = t6.BV_ID
AND t6.DPR_ID = t4.DPR_ID
INNER JOIN tb_ins t7
ON (t7.INS_ID = t4.INS_ID)
INNER JOIN tb_cpm t8
ON t8.BV_ID = t9.BV_ID
WHERE (t.BEGIN_DT > ? AND t.END_DT < ?)
) t
join tb_equipment t2 on t2.plant_unit = t.plant_unit
where (seqnum = 1
or seqnum = cnt);
I've got to make it work on Oracle 8i [I know it's a REALLY old version, but I have no choice since it's not my DB]. I've built this query in order to get the data from Oracle 8i: [I've changed CASE WHEN for DECODE and removed all the ANSI JOINs]
SELECT DECODE(SEQNUM, 1, T.DPR_N,CNT,'0') VALUE1,
DECODE(SEQNUM, 1, T.BEGIN_DT,CNT,T.END_DT) TIMESTAMP,
'090.' || T2.APP_NAAM
|| '.SUBBATCH_TRIGGER' TAGNAME1
FROM
(SELECT T.*,
T6.*,
ROW_NUMBER() OVER(PARTITION BY T.BATCH_ID, T.PLANT_UNIT,T6.DPR_ID ORDER BY T.BEGIN_DT) SEQNUM,
COUNT(*) OVER(PARTITION BY T.BATCH_ID, T.PLANT_UNIT,T6.DPR_ID) CNT
FROM tb_unit_step T ,
tb_equipment T2 ,
tb_rs3 T3 ,
tb_cpm T9 ,
tb_step T4 ,
tb_bv T5 ,
tb_bv_process T6 ,
tb_ins T7 ,
tb_cpm T8
WHERE T2.PLANT_UNIT = T.PLANT_UNIT
AND T.BATCH_ID = T3.BATCH_ID
AND (T9.BV_ID = T4.BV_ID
AND T.STAP_NR1 = T4.STAP_NR1
AND T.STAP_NR2 = T4.STAP_NR2)
AND T5.BV_ID = T9.BV_ID
AND (T9.BV_ID = T6.BV_ID
AND T6.DPR_ID = T4.DPR_ID)
AND T7.INS_ID = T4.INS_ID
AND T8.BV_ID = T9.BV_ID
AND (T.BEGIN_DT > '15-jul-2013'
AND T.END_DT < '01-aug-2014')
) T
,tb_equipment T2
WHERE T2.PLANT_UNIT = T.PLANT_UNIT
AND (T.SEQNUM = 1
OR SEQNUM = T.CNT)
;
The new query is definately not OK because it's taking forever to run. So what would be the correct form of the first query in order to get data from Oracle 8i?
UPDATE:
Result of the query:
ORA-01652: unable to extend temp segment by 128 in tablespace TEMP
01652. 00000 - "unable to extend temp segment by %s in tablespace %s"
*Cause: Failed to allocate an extent of the required number of blocks for
a temporary segment in the tablespace indicated.
*Action: Use ALTER TABLESPACE ADD DATAFILE statement to add one or more
files to the tablespace indicated.
Thanks in advance!
I don't see this condition in your Oracle 8 version:
t9.BACPM_ID = t3.BACPM_ID
That could explain the performance problem.
Related
select * from table1 t1 where t1.column1 = 'someValue' and ((t1.column2 =1) OR (sysdate < select t1.DateColumn2 + t2.DateColumn2/1440
from
table2 t2 where t1.column3 = t2.column3));
if t1.column2 =1 evaluates to false, I want to check another condition if time t1.DateColumn2 + t2.DateColumn2 is < sysdate . Oracle is throwing syntax error near or condition. Cant sysdate be used directly like that? Not sure where I am going wrong. Thanks
If I am guessing your intention correctly, you want an exists clause
select *
from table1 t1
where t1.column1 = 'someValue'
and ( (t1.column2 =1)
OR exists( select 1
from table2 t2
where t2.column3 = t1.column3
and sysdate < t1.DateColumn2 + t2.DateColumn2/1440 ));
Or just join the two tables in the outer query assuming there is at most 1 row in t2 per t1 row (if there is exactly 1 row you should do an inner join rather than a left outer join)
select t1.*
from table1 t1
left outer join table2 t2
on( t1.column3 = t2.column3 )
where t1.column2 = 1
or sysdate < t1.DateColumn2 + t2.DateColumn2/1440;
I've got this query in Oracle 8i:
select
decode(seqnum,
1 , '1',
cnt, '0'
) as value1,
decode(seqnum,
1 , t.BEGIN_DT,
cnt, t.END_DT
) 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');
I've recently asked the Stackoverflow community and they told me Oracle 8i doesn't support ansi joins.
how can I rewrite this query for Oracle 8i?
Thanks in advance!
select decode(seqnum, 1 , '1',
cnt, '0') as value1,
decode(seqnum, 1, t.BEGIN_DT,
cnt, t.END_DT) 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,
(select ID1,batch_id from SCH2.VW_BATCH) t2,
(select ID2,ID1 from SCH1.STEP) t3
where t.BATCH_ID = t2.BATCH_ID
and t3.ID1 = t2.ID1) t,
SCH2.TB_W_MACHINE t4
where t4.plant_unit = t.plant_unit
and (seqnum = 1 or seqnum = cnt)
AND (t.BEGIN_DT > '01-jan-2013' AND t.BEGIN_DT < '01-feb-2013');
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
I am running this query in Oracle 11g with no problem:
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');
But when I run it in Oracle 8i (8.7.1) it gives ORA-00933: SQL command not properly ended.
Is there anys special consideration I must know for running sql commands in Oracle 8i?
Thanks in advance
AFAK case command was introduced since 9i.
OK - trip--down-memory-lane time:
select decode(seqnum,
1, '1',
cnt, '0') as value1,
decode(seqnum,
1, t.BEGIN_DT,
cnt, t.END_DT) 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
INNER join (select ID1, batch_id
from SCH2.VW_BATCH) t2
on t.BATCH_ID = t2.BATCH_ID
INNER join (select ID2, ID1
from SCH1.STEP) t3
on t3.ID1 = t2.ID1) t
INNER 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');
Please see my code below as it is running too slowly with the CROSS APPLY.
How can I remove the CROSS APPLY and add something else that will run faster?
Please note I am using SQL Server 2008 R2.
;WITH MyCTE AS
(
SELECT
R.NetWinCURRENCYValue AS NetWin
,dD.[Date] AS TheDay
FROM
dimPlayer AS P
JOIN
dbo.factRevenue AS R ON P.playerKey = R.playerKey
JOIN
dbo.vw_Date AS dD ON Dd.dateKey = R.dateKey
WHERE
P.CustomerID = 12345)
SELECT
A.TheDay AS [Date]
,ISNULL(A.NetWin, 0) AS NetWin
,rt.runningTotal AS CumulativeNetWin
FROM MyCTE AS A
CROSS APPLY (SELECT SUM(NetWin) AS runningTotal
FROM MyCTE WHERE TheDay <= A.TheDay) AS rt
ORDER BY A.TheDay
CREATE TABLE #temp (NetWin money, TheDay datetime)
insert into #temp
SELECT
R.NetWinCURRENCYValue AS NetWin
,dD.[Date] AS TheDay
FROM
dimPlayer AS P
JOIN
dbo.factRevenue AS R ON P.playerKey = R.playerKey
JOIN
dbo.vw_Date AS dD ON Dd.dateKey = R.dateKey
WHERE
P.CustomerID = 12345;
SELECT
A.TheDay AS [Date]
,ISNULL(A.NetWin, 0) AS NetWin
,SUM(B.NetWin) AS CumulativeNetWin
FROM #temp AS A
JOIN #temp AS B
ON A.TheDay >= B.TheDay
GROUP BY A.TheDay, ISNULL(A.NetWin, 0);
Here https://stackoverflow.com/a/13744550/613130 it's suggested to use recursive CTE.
;WITH MyCTE AS
(
SELECT
R.NetWinCURRENCYValue AS NetWin
,dD.[Date] AS TheDay
,ROW_NUMBER() OVER (ORDER BY dD.[Date]) AS RN
FROM dimPlayer AS P
JOIN dbo.factRevenue AS R ON P.playerKey = R.playerKey
JOIN dbo.vw_Date AS dD ON Dd.dateKey = R.dateKey
WHERE P.CustomerID = 12345
)
, MyCTERec AS
(
SELECT C.TheDay AS [Date]
,ISNULL(C.NetWin, 0) AS NetWin
,ISNULL(C.NetWin, 0) AS CumulativeNetWin
,C.RN
FROM MyCTE AS C
WHERE C.RN = 1
UNION ALL
SELECT C.TheDay AS [Date]
,ISNULL(C.NetWin, 0) AS NetWin
,P.CumulativeNetWin + ISNULL(C.NetWin, 0) AS CumulativeNetWin
,C.RN
FROM MyCTERec P
INNER JOIN MyCTE AS C ON C.RN = P.RN + 1
)
SELECT *
FROM MyCTERec
ORDER BY RN
OPTION (MAXRECURSION 0)
Note that this query will work if you have 1 record == 1 day! If you have multiple records in a day, the results will be different from the other query.
As I said here, if you want really fast calculation, put it into temporary table with sequential primary key and then calculate rolling total:
create table #Temp (
ID bigint identity(1, 1) primary key,
[Date] date,
NetWin decimal(29, 10)
)
insert into #Temp ([Date], NetWin)
select
dD.[Date],
sum(R.NetWinCURRENCYValue) as NetWin,
from dbo.dimPlayer as P
inner join dbo.factRevenue as R on P.playerKey = R.playerKey
inner join dbo.vw_Date as dD on Dd.dateKey = R.dateKey
where P.CustomerID = 12345
group by dD.[Date]
order by dD.[Date]
;with cte as (
select T.ID, T.[Date], T.NetWin, T.NetWin as CumulativeNetWin
from #Temp as T
where T.ID = 1
union all
select T.ID, T.[Date], T.NetWin, T.NetWin + C.CumulativeNetWin as CumulativeNetWin
from cte as C
inner join #Temp as T on T.ID = C.ID + 1
)
select C.[Date], C.NetWin, C.CumulativeNetWin
from cte as C
order by C.[Date]
I assume that you could have duplicates dates in the input, but don't want duplicates in the output, so I grouped data before puting it into the table.