Eliminating NVL in WHERE Clause
Hi,
I've a condition in WHERE Clause as:
WHERE NVL(tab1.col1,'X') = NVL(tab2.col2,'X')
Now, I want to eliminate NVL to optimize the query.
Can any one suggest me, how do I do this?
Thanks,
Santhosh
SQL> create table test (id number,id2 number);
Table created.
SQL> create table test2 (id number,id2 number);
Table created.
SQL> create index test_indx on test(id2);
Index created.
SQL> create index test2_indx on test2(id2);
Index created.
SQL> insert into test
2 select level,level
3 from dual
4 connect by level <= 10000;
10000 rows created.
SQL> update test set id2 = null where mod(id,1000) = 0;
10 rows updated.
SQL> insert into test2
2 select level,8000+level
3 from dual
4 connect by level <= 10000;
10000 rows created.
SQL> update test2 set id2 = null where mod(id,1000) = 0;
10 rows updated.
SQL> explain plan for
2 select *
3 from test t1,test2 t2
4 where t1.id = t2.id
5 and nvl(t1.id2,-1) = nvl(t2.id2,-1);
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 2964437775
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 52 | 8 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID| TEST | 1 | 26 | 2 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 1 | 52 | 8 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL | TEST2 | 1 | 26 | 6 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | INDX1 | 1 | | 1 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
1 - filter(NVL("T1"."ID2",(-1))=NVL("T2"."ID2",(-1)))
4 - access("T1"."ID"="T2"."ID")
Note
- dynamic sampling used for this statement
21 rows selected.
SQL> create index indx11 on test(nvl(id2,-1));
Index created.
SQL> create index indx12 on test2(nvl(id2,-1));
Index created.
SQL> ed
Wrote file afiedt.buf
1 explain plan for
2 select *
3 from test t1,test2 t2
4 where t1.id = t2.id
5 and nvl(t2.id2,-1) = nvl(t1.id2,-1)
6* and t1.id > 9000
SQL> /
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 3509839790
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 52 | 3 (0)| 00:00:01 |
|* 1 | TABLE ACCESS BY INDEX ROWID | TEST | 1 | 26 | 2 (0)| 00:00:01 |
| 2 | NESTED LOOPS | | 1 | 52 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS BY INDEX ROWID| TEST2 | 1 | 26 | 1 (0)| 00:00:01 |
|* 4 | INDEX RANGE SCAN | INDX2 | 1 | | 1 (0)| 00:00:01 |
|* 5 | INDEX RANGE SCAN | INDX1 | 50 | | 1 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
1 - filter(NVL("T2"."ID2",(-1))=NVL("T1"."ID2",(-1)))
4 - access("T2"."ID">9000)
5 - access("T1"."ID"="T2"."ID")
filter("T1"."ID">9000)
Note
PLAN_TABLE_OUTPUT
- dynamic sampling used for this statement
24 rows selected.
user652588 wrote:Hi Blushadow,
Thanks for the reply.
You suggested me to use function based index. I'm unaware of it.
Could you please let me know, what are those and how can I use those?
And also, could you please let me know the functionality COALESCE?
Thanks,
Santhoshhttp://www.oracle.com/pls/db10g/search?remark=quick_search&word=function+based+index
http://download.oracle.com/docs/cd/B14117_01/server.101/b10759/functions019.htm#SQLRF00617
Similar Messages
-
NVL in where clause not working with UNIX parameters
Apparently this in a where clause does not work in UNIX scripts...
.... and trans_date between to_date('&1','YYYY/MM/DD HH24:MI:SS')
and to_date(NVL('&2','31-DEC-4712'),'YYYY/MM/DD HH24:MI:SS')
and to_date(NVL('','31-DEC-4712'),'YYYY/MM/DD HH24:MI:SS')
ERROR at line 14:
ORA-01858: a non-numeric character was found where a numeric was expected
How do I get around a null in UNIX? This works fine if both parameters are populated. Thanks.Jason ORCL wrote:
Apparently this in a where clause does not work in UNIX scripts...
.... and trans_date between to_date('&1','YYYY/MM/DD HH24:MI:SS')
and to_date(NVL('&2','31-DEC-4712'),'YYYY/MM/DD HH24:MI:SS')
and to_date(NVL('','31-DEC-4712'),'YYYY/MM/DD HH24:MI:SS')
ERROR at line 14:
ORA-01858: a non-numeric character was found where a numeric was expected
How do I get around a null in UNIX? This works fine if both parameters are populated. Thanks.it's nothing to do with unix at all - your date value doesn't match the format mask that you've entered:
'31-DEC-4712' doesn't map to 'YYYY/MM/DD HH24:MI:SS' in any universe unfortunately. -
NVL with host variables in a where clause
Does anyone know if using a host variable in a WHERE clause with
the NVL function will actually work if the host variable is null
without using the indicator variable too?
In other words if the variable ":new_prmy_numb" which was
selected previously is actually null, will the NVL know that it
is null without the indicator variable being listed also? The
person at our company who has this in their code says it works
and the rest of us don't see how.
Example:
SELECT recd_a_id from ADDR
WHERE
NVL(prmy_numb,' ') = NVL(:new_prmy_numb,' ')well firstly have you tried it to see if it works? That would seems to be a rather obvious step, I would imagine.
Anyway, I don't see anything wrong with the code, except that it might be optimized better ...
SELECT recd_a_id from ADDR
WHERE
(prmy_numb = :new_prmy_numb
or (:new_prmy_numb is null and prmy_numb is null))
... might stand more chance of using an index on the column prmy_numb -
Trouble with OR in where clause
Hello,
I'm having trouble with execution speed. The problem seems to be with using OR in my where clause.
Here's the meat of the function where i_pledge_number is an input parm:
BEGIN
SELECT /*+ INDEX (pp) */ SUM(pp.prim_pledge_amount)
INTO return_amount
FROM
primary_pledge pp
WHERE
-- Get total if multiple allocations
pp.prim_pledge_number IN
(SELECT pc.pledge_number
FROM pledge_codes pc
WHERE pc.pledge_code_type = 'M'
AND pc.pledge_code = 'AC'
AND lpad(pc.pledge_comment,10,'0') = i_pledge_number)
-- Get total if single allocation
OR pp.prim_pledge_number = i_pledge_number;
RETURN return_amount;
END;
If I comment out either half of the OR statement (either the subquery or the pp.prim_pledge_number = i_pledge_number half) the function returns a value in .02 seconds. If I leave the OR in, it takes 2.764 seconds to execute?? Can someone please show me a better way (faster) to do this? I tried using nvl() around the subquery but couldn't get it to compile.
ThanksThese things are difficult to diagnose remotely, but here is something you can try....
SELECT */ SUM(pp.prim_pledge_amount)
INTO return_amount
FROM primary_pledge pp
WHERE pp.prim_pledge_number IN (SELECT pc.pledge_number
FROM pledge_codes pc
WHERE pc.pledge_code_type = 'M'
AND pc.pledge_code = 'AC'
AND lpad(pc.pledge_comment,10,'0') = i_pledge_number
UNION ALL
SELECT i_pledge_number FROM dual)
RETURN return_amount;
END;If that doesn't do anything (and it might well not) there are a large number of different ways we can recast this query. To save us further guessing please give us more details: execution plans, database version number, volumetrics.
Cheers, APC -
Exclude duplicate values on SQL where clause statement
Hi!
Are some posibilities to exclude duplicate values do not using sql aggregate functions in main select statement?
Priview SQL statement
SELECT * FROM
select id,hin_id,name,code,valid_date_from,valid_date_to
from diaries
QRSLT
WHERE (hin_id = (SELECT NVL(historic_id,id)FROM tutions where id=/*???*/ 59615))
AND NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy')) <= (SELECT NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy'))FROM tutions where id= /*???*/ 59615)
AND trunc(valid_date_from) >=(SELECT trunc(valid_date_from)FROM tutions where id= /*???*/ 59615)
The result
ID HIN_ID NAME CODE VALID_DATE FROM VALID_DATE_TO
50512
59564
RE TU
01
07.06.2013 16:32:15
07.06.2013 16:33:28
50513
59564
TT2
02
07.06.2013 16:33:23
07.06.2013 16:33:28
50515
59564
TT2
02
07.06.2013 16:33:28
07.06.2013 16:34:42
50516
59564
ROD
03
07.06.2013 16:34:37
07.06.2013 16:34:42
VALID_DATE_TO & AND VALID_DATE_FROM tutions
07.06.2013 16:34:42
15.07.2013 10:33:23
In this case i got duplicate of entry TT2 id 50513 In main select statement cant use agregate functions are even posible to exclude this value from result modifying only the QLRST WHERE clause (TRUNC need to be here)
THANKS FOR ANY TIP !
ID.Hi, Ok this is working in this case
SELECT * FROM
select id,hin_id,name,code,valid_date_from,valid_date_to
from diaries ahs
QRSLT
WHERE (hin_id = (SELECT NVL(historic_id,id)FROM aip_healthcare_tutions where id=/*???*/ 59615))
AND NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy')) <= (SELECT NVL(valid_date_to,to_date('22.12.2999','dd.mm.yyyy'))FROM tutions where id= /*???*/ 59615)
AND trunc(valid_date_from) >=(SELECT trunc(valid_date_from)FROM tutions where id= /*???*/ 59615)
AND NOT EXISTS
(SELECT null FROM diaries ahs WHERE ahs.valid_date_from < QRSLT.valid_date_from
AND QRSLT.hin_id=ahs.hin_id
AND QRSLT.code=ahs.code);
Result
50512
59564
RE TU
01
07.06.2013 16:32:15
07.06.2013 16:33:28
50513
59564
TT2
02
07.06.2013 16:33:23
07.06.2013 16:33:28
50516
59564
ROD
03
07.06.2013 16:34:37
07.06.2013 16:34:42
But if the Data in tutions row are theese(valid_date_to-null) then NO ROWS are returning and its logical because in full result list Valid_date_from column are logical incorect
valid_date_from valid_date_to
15.07.2013 10:33:23
NULL
ID HIN_ID NAME CODE VALID_DATE FROM VALID_DATE_TO
50510
59564
RE TU
01
07.06.2013 16:33:28
50511
59564
TT2
02
07.06.2013 16:34:41
50514
59564
ROD
03
07.06.2013 16:34:41
50520
59564
Params
04
03.07.2013 21:01:30
50512
59564
RE TU
01
07.06.2013 16:32:15
07.06.2013 16:33:28
50513
59564
TT2
02
07.06.2013 16:33:23
07.06.2013 16:33:28
50515
59564
TT2
02
07.06.2013 16:33:28
07.06.2013 16:34:42
50516
59564
ROD
03
07.06.2013 16:34:37
07.06.2013 16:34:42
Are that posible modifying where statement if the valid_date_to in tutions are null then theese records where in diary valid_date_to is null is correct to, but need to stay previos logic
D HIN_ID NAME CODE VALID_DATE FROM VALID_DATE_TO
50510
59564
RE TU
01
07.06.2013 16:33:28
null
50511
59564
TT2
02
07.06.2013 16:34:41
null
50514
59564
ROD
03
07.06.2013 16:34:41
null
50520
59564
Params
04
03.07.2013 21:01:30
null
Thanks !
ID. -
Does the 'default where clause' query select the ROWID by default ?
Hi ,
The query in default where property of a data block is as follows:
global.prim_lang = :global.user_lang
and upper(group_name) like upper('%' || :B_apply_inclusions.TI_group_desc || '%')
UNION ALL
select g.rowid, g.group_no
from table1 t,
table 2 g
where :global.prim_lang != :global.user_lang
and upper(g.group_name) = t.key(+)
and :global.user_lang = t.lang(+)
and upper(nvl(t.translated_value, g.group_name)) like upper('%' || :B_apply_inclusions.TI_group_desc || '%')
The g.rowid was added in the UNIONALL portion of the query because the first part of the query was bringing rowid as well.
We are in 10.1.2.3.0 forms version.
However for a user in forms verion 10.1.2.0.2, the query is giving an error " Unable to perform query " - due to mismatch in the number of columns selected in the query union.
because for this user, rowid is not selected as part of default where clause query( 1st part of the query before the unionalll).
If g.rowid is removed from the 2nd part of the query , it errors out in 10.1.2.3.0 forms version.
Could you kindly clarify when this rowid will also be selected by the default where clause of a block and why this issue is occuring?Is this issue related to forms version or any other property of the block? Is it is version based, is there a patch available to deal with the same?
Thanks in Advance.You normally change the default_where block property just when you want to chnage the filter conditions for what is selected from a given block data source.
Querries with union or minus will confuse forms as to the rowid and will no longer be albe to perform the default insert/update/delete, not knowing the rowid and the table to perform the dml on.
A from clause query will be the best way to change dynamically the tables you select from and also the where. But, by using that, if you wish to insert/update/delete, you will have to use on-insert/update/delete triggers where the processing will have to rely on some primary key columns and not on rowid.
Or, instead of a from-clause, you may use a view, but that will definitely be less flexible than a from clause query. -
No output for XML Publisher Report using CASE/DECODE in Where Clause
Hi,
I've a business requirement to modify an existing report which has two input parameters,
-> p_statcode (Closed Status) which can have values 'Y' or 'N'
-> p_overdue (Overdue Flag) which can have values 'Y' or 'N'
The Overdue Flag is an evaluated column having values of Y/N and it is evaluated as follows,
ONTF_MOD_VAL(NVL (
(TRUNC (SYSDATE)
- (TO_DATE (oe_order_lines.attribute18,
'DD-MON-RRRR')
+ TO_NUMBER (fnd_lookup_values.meaning))),
0
overdue_flagThe user requirement now is they needs to be a third option for parameter p_overdue called ALL,
passing which the output should include records having
p_statcode is Y ELSE p_statcode is N AND p_overdue is Y OR p_overdue is N
In other words records having both Y and N vlaues for Overdue Flag have to be returned irrespective of the value given to Closed Status.
Original where clause in the Data Definition file is as follows,
WHERE Closed_Status = nvl(:p_statcode,Closed_Status)
AND overdue_flag = nvl(:p_overdue,overdue_flag)My modified code is as follows,
WHERE Closed_Status = NVL (:p_statcode, Closed_Status)
AND overdue_flag = (CASE
WHEN :p_overdue = 'Y' THEN 'Y'
WHEN :p_overdue = 'N' THEN 'N'
ELSE overdue_flag
END)
OR
WHERE Closed_Status = NVL (:p_statcode, Closed_Status)
AND overdue_flag = DECODE (:p_overdue, 'Y', 'Y', 'N', 'N',overdue_flag)Both approaches have the same problem.
The output is in EXCEL format. The modified query works fine for p_overdue as Y or N but when p_overdue is passed as ALL it returns an empty EXCEL sheet with just the report output column headers.
Any help as to why this is the case ?? What is wrong in my approach ?
Regards,
Vishalnot clear about p_overdue = ALL
which values needed for p_overdue = ALL ?
try smth like
WHERE Closed_Status = NVL (:p_statcode, Closed_Status)
AND (
overdue_flag = DECODE (:p_overdue, 'Y', 'Y', 'N', 'N',overdue_flag) and :p_overdue != 'ALL'
or
:p_overdue = 'ALL' and (overdue_flag = 'Y' or overdue_flag = 'N')
)for overdue_flag which has more then 'Y', 'N' values
if overdue_flag only in ('Y','N') then
WHERE Closed_Status = NVL (:p_statcode, Closed_Status)
AND (
overdue_flag = DECODE (:p_overdue, 'Y', 'Y', 'N', 'N',overdue_flag) and :p_overdue != 'ALL'
or
:p_overdue = 'ALL'
) -
Using regexp_instr in a where clause - invalid relational operator
Whey I try to run this query in TOAD I get an ORA-00920: invalid relational operator error. It's part of a 10g stored procedure. When I highlight it and run it it prompts me for the missing values and then the error pops up. The AND in line 4 is highlighted.
select CRIME_CLASSIFICATION_ID, crime_type, nvl(count(CRIME_CLASSIFICATION_ID),0) as CRIMECNT
From vaps.vw_offenses
where regexp_instr(valoc,to_char(location_id))
AND ( fromdate is null or
offense_date between to_date(fromdate, 'mm/dd/yyyy') AND to_date(todate,'mm/dd/yyyy')
group by crime_classification_id, crime_typeHi,
Review what REGEXP_INSTR does: it returns a NUMBER.
Your WHERE clause couldn't make any sense if you used any other kind of NUMBER expression in that place, e.g. a NUMBER literal such as 12:
select CRIME_CLASSIFICATION_ID, crime_type, nvl(count(CRIME_CLASSIFICATION_ID),0) as CRIMECNT
From vaps.vw_offenses
where 12 -- This is obviously wrong
AND ( fromdate is null or
offense_date between to_date(fromdate, 'mm/dd/yyyy') AND to_date(todate,'mm/dd/yyyy')
group by crime_classification_id, crime_type
It's not going to work any better with a function (like REGEXP_INSTR) that returns a NUMBER.
How can you fix it? That depends on what you want to do. Why are you calling REGEXP_INSTR? What is that condition checking?
Whenever you have a problem, please post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) from all tables involved, so that the people who want to help you can re-create the problem and test their ideas.
Also post the results you want from that data, and an explanation of how you get those results from that data, with specific examples.
Always say which version of Oracle you're using (for example, 11.2.0.2.0).
See the forum FAQ: https://forums.oracle.com/message/9362002 -
Slow split table export (R3load and WHERE clause)
For our split table exports, we used custom coded WHERE clauses. (Basically adding additional columns to the R3ta default column to take advantage of existing indexes).
The results have been good so far. Full tablescans have been eliminated and export times have gone down, in some cases, tables export times have improved by 50%.
However, our biggest table, CE1OC01 (120 GB), continues to be a bottleneck. Initially, after using the new WHERE clause, it looked like performance gains were dramatic, with export times for the first 5 packages dropping from 25-30 hours down to 1 1/2 hours.
However, after 2 hours, the remaining CE1OC01 split packages have shown no improvement. This is very odd because we are trying to determine why part of the table exports very fast, but other parts are running very slow.
Before the custom WHERE clauses, the export server had run into issues with SORTHEAP being exhausted, so we thought that might be the culprit. But that does not seem to be an issue now, since the improved WHERE clauses have reduced or eliminated excessive sorting.
I checked the access path of all the CE1OC01 packages, through EXPLAIN, and they all access the same index to return results. The execution time in EXPLAIN returns similar times for each of the packages:
CE1OC01-11: select * from CE1OC01 WHERE MANDT='212'
AND ("BELNR" > '0124727994') AND ("BELNR" <= '0131810250')
CE1OC01-19: select * from CE1OC01 WHERE MANDT='212'
AND ("BELNR" > '0181387534') AND ("BELNR" <= '0188469413')
0 SELECT STATEMENT ( Estimated Costs = 8.448E+06 [timerons] )
|
--- 1 RETURN
|
--- 2 FETCH CE1OC01
|
------ 3 IXSCAN CE1OC01~4 #key columns: 2
query execution time [millisec] | 333
uow elapsed time [microsec] | 429,907
total user CPU time [microsec] | 0
total system cpu time [microsec] | 0
Both queries utilize an index that has fields MANDT and BELNR. However, during R3load, CE1OC01-19 finishes in an hour and a half, whereas CE1OC01-11 can take 25-30 hours.
I am wondering if there is anything else to check on the DB2 access path side of things or if I need to start digging deeper into other aggregate load/infrastructure issues. Other tables don't seem to exhibit this behavior. There is some discrepancy between other tables' run times (for example, 2-4 hours), but those are not as dramatic as this particular table.
Another idea to test is to try and export only 5 parts of the table at a time, perhaps there is a throughput or logical limitation when all 20 of the exports are running at the same time. Or create a single column index on BELNR (default R3ta column) and see if that shows any improvement.
Anyone have any ideas on why some of the table moves fast but the rest of it moves slow?
We also notice that the "fast" parts of the table are at the very end of the table. We are wondering if perhaps the index is less fragmented in that range, a REORG or recreation of the index may do this table some good. We were hoping to squeeze as many improvements out of our export process as possible before running a full REORG on the database. This particular index (there are 5 indexes on this table) has a Cluster Ratio of 54%, so, perhaps for purposes of the export, it may make sense to REORG the table and cluster it around this particular index. By contrast, the primary key index has a Cluster Ratio of 86%.
Here is the output from our current run. The "slow" parts of the table have not completed, but they average a throughput of 0.18 MB/min, versus the "fast" parts, which average 5 MB/min, a pretty dramatic difference.
package time start date end date size MB MB/min
CE1OC01-16 10:20:37 2008-11-25 20:47 2008-11-26 07:08 417.62 0.67
CE1OC01-18 1:26:58 2008-11-25 20:47 2008-11-25 22:14 429.41 4.94
CE1OC01-17 1:26:04 2008-11-25 20:47 2008-11-25 22:13 416.38 4.84
CE1OC01-19 1:24:46 2008-11-25 20:47 2008-11-25 22:12 437.98 5.17
CE1OC01-20 1:20:51 2008-11-25 20:48 2008-11-25 22:09 435.87 5.39
CE1OC01-1 0:00:00 2008-11-25 20:48 0.00
CE1OC01-10 0:00:00 2008-11-25 20:48 152.25
CE1OC01-11 0:00:00 2008-11-25 20:48 143.55
CE1OC01-12 0:00:00 2008-11-25 20:48 145.11
CE1OC01-13 0:00:00 2008-11-25 20:48 146.92
CE1OC01-14 0:00:00 2008-11-25 20:48 140.00
CE1OC01-15 0:00:00 2008-11-25 20:48 145.52
CE1OC01-2 0:00:00 2008-11-25 20:48 184.33
CE1OC01-3 0:00:00 2008-11-25 20:48 183.34
CE1OC01-4 0:00:00 2008-11-25 20:48 158.62
CE1OC01-5 0:00:00 2008-11-25 20:48 157.09
CE1OC01-6 0:00:00 2008-11-25 20:48 150.41
CE1OC01-7 0:00:00 2008-11-25 20:48 175.29
CE1OC01-8 0:00:00 2008-11-25 20:48 150.55
CE1OC01-9 0:00:00 2008-11-25 20:48 154.84Hi all, thanks for the quick and extremely helpful answers.
Beck,
Thanks for the health check. We are exporting the entire table in parallel, so all the exports begin at the same time. Regarding the SORTHEAP, we initially thought that might be our problem, because we were running out of SORTHEAP on the source database server. Looks like for this run, and the previous run, SORTHEAP has remained available and has not overrun. That's what was so confusing, because this looked like a buffer overrun.
Ralph,
The WHERE technique you provided worked perfectly. Our export times have improved dramatically by switching to the forced full tablescan. Being always trained to eliminate full tablescans, it seems counterintuitive at first, but, given the nature of the export query, combined with the unsorted export, it now makes total sense why the tablescan works so much better.
Looks like you were right, in this case, the index adds too much additional overhead, and especially since our Cluster Ratio was terrible (in the 50% range), so the index was definitely working against us, by bouncing all over the place to pull the data out.
We're going to look at some of our other long running tables and see if this technique improves runtimes on them as well.
Thanks so much, that helped us out tremendously. We will verify the data from source to target matches up 1 for 1 by running a consistency check.
Look at the throughput difference between the previous run and the current run:
package time start date end date size MB MB/min
CE1OC01-11 40:14:47 2008-11-20 19:43 2008-11-22 11:58 437.27 0.18
CE1OC01-14 39:59:51 2008-11-20 19:43 2008-11-22 11:43 427.60 0.18
CE1OC01-12 39:58:37 2008-11-20 19:43 2008-11-22 11:42 430.66 0.18
CE1OC01-13 39:51:27 2008-11-20 19:43 2008-11-22 11:35 421.09 0.18
CE1OC01-15 39:49:50 2008-11-20 19:43 2008-11-22 11:33 426.54 0.18
CE1OC01-10 39:33:57 2008-11-20 19:43 2008-11-22 11:17 429.44 0.18
CE1OC01-8 39:27:58 2008-11-20 19:43 2008-11-22 11:11 417.62 0.18
CE1OC01-6 39:02:18 2008-11-20 19:43 2008-11-22 10:45 416.35 0.18
CE1OC01-5 38:53:09 2008-11-20 19:43 2008-11-22 10:36 413.29 0.18
CE1OC01-4 38:52:34 2008-11-20 19:43 2008-11-22 10:36 424.06 0.18
CE1OC01-9 38:48:09 2008-11-20 19:43 2008-11-22 10:31 416.89 0.18
CE1OC01-3 38:21:51 2008-11-20 19:43 2008-11-22 10:05 428.16 0.19
CE1OC01-2 36:02:27 2008-11-20 19:43 2008-11-22 07:46 409.05 0.19
CE1OC01-7 33:35:42 2008-11-20 19:43 2008-11-22 05:19 414.24 0.21
CE1OC01-16 9:33:14 2008-11-20 19:43 2008-11-21 05:16 417.62 0.73
CE1OC01-17 1:20:01 2008-11-20 19:43 2008-11-20 21:03 416.38 5.20
CE1OC01-18 1:19:29 2008-11-20 19:43 2008-11-20 21:03 429.41 5.40
CE1OC01-19 1:16:13 2008-11-20 19:44 2008-11-20 21:00 437.98 5.75
CE1OC01-20 1:14:06 2008-11-20 19:49 2008-11-20 21:03 435.87 5.88
PLPO 0:52:14 2008-11-20 19:43 2008-11-20 20:35 92.70 1.77
BCST_SR 0:05:12 2008-11-20 19:43 2008-11-20 19:48 29.39 5.65
CE1OC01-1 0:00:00 2008-11-20 19:43 0.00
558:13:06 2008-11-20 19:43 2008-11-22 11:58 8171.62
package time start date end date size MB MB/min
CE1OC01-9 9:11:58 2008-12-01 20:14 2008-12-02 05:26 1172.12 2.12
CE1OC01-5 9:11:48 2008-12-01 20:14 2008-12-02 05:25 1174.64 2.13
CE1OC01-4 9:11:32 2008-12-01 20:14 2008-12-02 05:25 1174.51 2.13
CE1OC01-8 9:09:24 2008-12-01 20:14 2008-12-02 05:23 1172.49 2.13
CE1OC01-1 9:05:55 2008-12-01 20:14 2008-12-02 05:20 1188.43 2.18
CE1OC01-2 9:00:47 2008-12-01 20:14 2008-12-02 05:14 1184.52 2.19
CE1OC01-7 8:54:06 2008-12-01 20:14 2008-12-02 05:08 1173.23 2.20
CE1OC01-3 8:52:22 2008-12-01 20:14 2008-12-02 05:06 1179.91 2.22
CE1OC01-10 8:45:09 2008-12-01 20:14 2008-12-02 04:59 1171.90 2.23
CE1OC01-6 8:28:10 2008-12-01 20:14 2008-12-02 04:42 1172.46 2.31
PLPO 0:25:16 2008-12-01 20:14 2008-12-01 20:39 92.70 3.67
90:16:27 2008-12-01 20:14 2008-12-02 05:26 11856.91 -
Query Tuning - using CASE statement in the WHERE clause
Hi All,
My query has been modified to use a CASE statement in the WHERE clause to consider data from certain columns based on a parameter value. This modified query is doing a full table scan and running endlessly. Please suggest what may be done to improve its performance:
Query:
SELECT LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))) AS summary_date,
os.acctnum,
os.avieworigin_refid,
COUNT(1) cnt_articleview,
SUM(NVL(autocompletedterm,0)) cnt_autocompletedterm
FROM TABLE1 os
WHERE os.acctnum IS NOT NULL
AND os.avieworigin_refid IS NOT NULL
AND os.requestdatetime IS NOT NULL
AND UPPER(os.success_ind) = 'S'
AND CASE WHEN
Param_ValueToCheck = 'FULL' AND get_date_timestamp(os.requestdatetime) BETWEEN
TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND
TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
THEN 1
WHEN
Param_ValueToCheck = 'INCR' AND os.entry_createddate BETWEEN
TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND
TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
THEN 1
END = 1
AND CASE WHEN
Param_ValueToCheck = 'FULL' AND os.entry_CreatedDate BETWEEN
TO_DATE('01-APR-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') AND
TO_DATE('07-JUN-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
THEN 1
WHEN
Param_ValueToCheck = 'INCR' THEN 1
END = 1
GROUP BY LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))), os.acctnum,os.avieworigin_refid;Table Description:
(Number of rows : approx > 600,000,000)
Name Null Type
ARTICLEID NOT NULL NUMBER(20)
USERKEY NUMBER(10)
AVIEWORIGIN_REFID VARCHAR2(10)
SUCCESS_IND VARCHAR2(2)
ENTRY_CREATEDDATE DATE
CREATED_BY VARCHAR2(10)
FILENUMBER NUMBER(10)
LINENUMBER NUMBER(10)
ACCTNUM VARCHAR2(10)
AUTOCOMPLETEDTERM NUMBER(2)
REQUESTDATETIME VARCHAR2(19)Explain Plan
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 2224314832
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
| 0 | SELECT STATEMENT | | 590 | 33040 | 2501K (1)| 08:20:15 | | |
| 1 | HASH GROUP BY | | 590 | 33040 | 2501K (1)| 08:20:15 | | |
| 2 | PARTITION RANGE ALL| | 590 | 33040 | 2501K (1)| 08:20:15 | 1 |1048575|
|* 3 | TABLE ACCESS FULL | TABLE1 | 590 | 33040 | 2501K (1)| 08:20:15 | 1 |1048575|
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
3 - filter(UPPER("OS"."SUCCESS_IND")='S' AND CASE WHEN ('FULL'='FULL' AND
"OS"."ENTRY_CREATEDDATE">=TO_DATE(' 2011-04-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"OS"."ENTRY_CREATEDDATE"<=TO_DATE(' 2011-06-07 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) THEN 1 WHEN
'FULL'='INCR' THEN 1 END =1 AND "OS"."REQUESTDATETIME" IS NOT NULL AND CASE WHEN ('FULL'='FULL'
AND "ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")>=TO_DATE(' 2011-05-01 00:00:00', 'syyyy-mm-dd
hh24:mi:ss') AND "ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")<=TO_DATE(' 2011-05-31 00:00:00',
'syyyy-mm-dd hh24:mi:ss')) THEN 1 WHEN ('FULL'='INCR' AND "OS"."ENTRY_CREATEDDATE">=TO_DATE('
2011-05-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND "OS"."ENTRY_CREATEDDATE"<=TO_DATE('
PLAN_TABLE_OUTPUT
2011-05-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss')) THEN 1 END =1 AND "OS"."ACCTNUM" IS NOT NULL AND
"OS"."AVIEWORIGIN_REFID" IS NOT NULL)Edited by: Chaitanya on Jun 9, 2011 2:44 AM
Edited by: Chaitanya on Jun 9, 2011 2:47 AMHi Dom,
Modified Query:
SELECT LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))) AS summary_date,
os.acctnum,
os.avieworigin_refid,
COUNT(1) cnt_articleview,
SUM(NVL(autocompletedterm,0)) cnt_autocompletedterm
FROM TABLE1 os
WHERE os.acctnum IS NOT NULL
AND os.avieworigin_refid IS NOT NULL
AND os.requestdatetime IS NOT NULL
AND UPPER(os.success_ind) = 'S'
AND (('FULL' = 'FULL'
AND (get_date_timestamp(os.requestdatetime) BETWEEN TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
AND TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
AND os.entry_CreatedDate BETWEEN TO_DATE('01-APR-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
AND TO_DATE('07-JUN-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
OR ('FULL' = 'INCR'
AND os.entry_createddate BETWEEN TO_DATE('01-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS')
AND TO_DATE('31-MAY-2011 00:00:00','DD-MON-YYYY HH24:MI:SS') ))
GROUP BY LAST_DAY(TRUNC(TO_TIMESTAMP(os.requestdatetime, 'yyyymmddhh24:mi:ss.ff4'))), os.acctnum,os.avieworigin_refid;Execute Plan:
PLAN_TABLE_OUTPUT
Plan hash value: 3615447714
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | Pstart| Pstop |
| 0 | SELECT STATEMENT | | 25125 | 1374K| | 407K (1)| 01:21:36 | | |
| 1 | HASH GROUP BY | | 25125 | 1374K| 3768K| 407K (1)| 01:21:36 | | |
| 2 | PARTITION RANGE ITERATOR| | 25125 | 1374K| | 407K (1)| 01:21:32 | 29 | 31 |
|* 3 | TABLE ACCESS FULL | TABLE1 | 25125 | 1374K| | 407K (1)| 01:21:32 | 29 | 31 |
PLAN_TABLE_OUTPUT
Predicate Information (identified by operation id):
3 - filter("OS"."ENTRY_CREATEDDATE">=TO_DATE(' 2011-04-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
UPPER("OS"."SUCCESS_IND")='S' AND "OS"."REQUESTDATETIME" IS NOT NULL AND
"ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")>=TO_DATE(' 2011-05-01 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"ODS"."GET_DATE_TIMESTAMP"("REQUESTDATETIME")<=TO_DATE(' 2011-05-31 00:00:00', 'syyyy-mm-dd hh24:mi:ss') AND
"OS"."ACCTNUM" IS NOT NULL AND "OS"."AVIEWORIGIN_REFID" IS NOT NULL AND "OS"."ENTRY_CREATEDDATE"<=TO_DATE('
2011-06-07 00:00:00', 'syyyy-mm-dd hh24:mi:ss'))Edited by: Chaitanya on Jun 9, 2011 4:51 AM -
Hi Gurus,
I'd like to filter the data displayed in a report according to the date,we have an agenda for meetings,when I open the meetings report,it should display only the meetings of today,here what I did:
where meeting_date =
nvl(to_char(:tday,'dd-mm-yyyy'),to_char(sysdate,'dd-mm-yyyy'))this where clause is put in the query of the region source,
tday is a date picker to allow the user to change the date if he wants to navigate to other dates (other than today)
It gives me the error 'ora-01722'
where I went wrong?
Putting in mind that the meeting_date column contains meeting time too,what ever the meeting time is,if it is for today it should be displayed.
MohammadHi,
Not sure if this will help but maybe you could try:
where to_char(meeting_date,'dd-mm-yyyy') =
nvl(to_char(:tday,'dd-mm-yyyy'),to_char(sysdate,'dd-mm-yyyy'))
or perhaps this one:
where to_char(meeting_date,'dd-mm-yyyy') =
nvl(:tday,to_char(sysdate,'dd-mm-yyyy'))
Thanks,
Richard. -
Help:alternate for calling function in where clause
Hi ,
In below query i'm calling function in where clause to avoid COMPLETE status records,due to this query taking 700 secs to return result.If i'm remove below function condition it's returning results with in 5 secs.Can you some one advice to any alternate idea for this?
WHERE mark_status != 'COMPLETE'
SELECT assessment_school,
subject,
subject_option,
lvl,
component,mark_status,
mark_status
NULL AS grade_status,
NULL AS sample_status,
:v_year,
:v_month,
:v_formated_date,
:v_type,
cand_lang
FROM
(SELECT assessment_school,
subject,
subject_option,
lvl,
programme,
component,
paper_code,
cand_lang,
mark_entry.get_ia_entry_status(:v_year, :v_month, assessment_school, subject_option, lvl, cand_lang, component, paper_code) AS mark_status
FROM
(SELECT DISTINCT ccr.assessment_school,
ccr.subject,
ccr.subject_option,
ccr.lvl,
ccr.programme,
ccr.language AS cand_lang,
ccr.paper_code,
ccr.component
FROM candidate_component_reg ccr
WHERE ccr.split_session_year = :v_year
AND ccr.split_session_month = :v_month
AND EXISTS
(SELECT 1
FROM IBIS.subject_component sc
WHERE sc.year = ccr.split_session_year
AND sc.month = ccr.split_session_month
AND sc.paper_code = ccr.paper_code
AND sc.assessment_type = 'INTERNAL'
AND sc.subject_option NOT LIKE '%self taught%'
AND sc.component NOT IN ('PERFORMANCE PRODUCTION','PRESENTATION WORK','REFLECTIVE PROJECT','SPECIAL SYLLABUS INT. ASSESSMENT')
AND NVL(ccr.withdrawn,'N') = 'N'
AND ccr.mark_status != 'COMPLETE'
AND EXISTS
(SELECT 1
FROM school s
WHERE s.school_code = ccr.assessment_school
AND s.training_school = 'N'
WHERE mark_status != 'COMPLETE';One thing you can test quickly is to put the function call in it's own select ...from dual.
This might make a difference.
However, only you can check this, I don't have your tables or data.
So, what happens if you use:
paper_code,
cand_lang,
(select mark_entry.get_ia_entry_status(:v_year, :v_month, assessment_school, subject_option, lvl, cand_lang, component, paper_code) from dual ) AS mark_status
FROM
(SELECT DISTINCT ccr.assessment_school, --<< is the DISTINCT really needed?
ccr.subject,
ccr.subject_option,
...Also, try to find out the purpose of that above DISTINCT, is it really needed or is there some join missing? -
Hi all
We can use decode function in the Select columns as well as Group by Columns as well as Having Clause
Can we use decode function in the where clause also. If yes can u give small sample
Suresh Bansal""DECODE in the WHERE clause"
http://psoug.org/reference/decode_case.html
WHERE empid = DECODE(posn,
0, st.areadir,
1, st.areamgr,
2, NVL(st.storemgr1, st.storemgr2),
3, NVL(st.asstmgr1, NVL(st.asstmgr2,
st.asstmgr3))) -
Outer join with a WHERE clause
hi, this is driving me round the bend. I thought i was ok with sql joins and the like, but im really struggling on this one.
I have table A (for argument sake tblRegion) and table B (tblBranch). if i want to return everything i would do something like this:-
select * from tblRegion join tblBranch on tblRegion.id=tblBranch.reg_id.
If i wanted to return all regions even if they do have a branch associated i would do something like this:-
select * from tblRegion left outer join tblBranch on tblRegion.id=tblBranch.reg_id.
My problem is, I want to return all Regions and use a WHERE clause to narrow the Branch results.
I've tried something like this but it doesnt work
select * from tblRegion left outer join tblBranch on tblRegion.id=tblBranch.reg_id WHERE branch.name like 'LONDON%'
Is there anyway i can return all branches where name is like LONDON, and STILL return all Region if there is no data for that Region?
Do i need to use a nested select statement maybe?
Many thanks in anticipation somebody will save me from my current madness. DavidCheck this link. It explains the most common problem/coding error while using outer join.
http://www.orafaq.com/node/855
Effectively in your case you need the following condition in your where clause
where nvl(branch.name,'LONDON') like 'LONDON%'
Hope that helps.
Regards
Raj -
How to use the MAX DATE condition in WHERE CLAUSE FILEDS
Hi,
I am trying to fetch the result for getting maximun date but when i try to execute the query i am getting the error as follows.
CONDITION : trunc(max(RD.DATERECEIVED)) BETWEEN TO_DATE('01/08/2011','DD/MM/YYYY') AND TO_DATE('01/08/2011','DD/MM/YYYY')
ERROR: Group function is not allowed here.
CHEERS,
PRABU AMMAIAPPANI see a couple of problems here.
First, what you posted below is not a syntactically valid query. It seems to be part of a larger query, specifically, this looks to be only the GROUP BY clause of a query.
Prabu ammaiappan wrote:
Hi,
I Have a group function in the Query. Below is the Query i have used it,
GROUP BY S.FREIGHTCLASS,
R.CONTAINERKEY,
S.SKU,
S.DESCR ||S.DESCRIPTION2,
S.PVTYPE,
RD.LOTTABLE06,
R.WAREHOUSEREFERENCE,
RD.TOLOC,
R.ADDWHO,
R.TYPE,
S.CWFLAG,
S.STDNETWGT,
S.ORDERUOM,
R.ADDDATE,
C.DESCRIPTION,
(CASE WHEN P.POKEY LIKE '%PUR%' THEN 'NULL' ELSE to_char(P.PODATE,'dd/mm/yyyy') END),
NVL((CASE WHEN R.ADDWHO='BOOMI' THEN RDD.SUPPLIERNAME END),SS.COMPANY),
RDD.BRAND,
S.NAPA,
RD.RECEIPTKEY,
R.SUSR4,
P.POKEY,
RDD.SUSR1,
r.STATUS, DECODE(RDD.SUSR2,' ',0,'',0,RDD.SUSR2),
rd.SUSR3Second, the answer to your primary question, "How do I add a predicate with with a MAX() function to my where clause?" is that you don't. As you discovered, if you attempt to do so, you'll find it doesn't work. If you stop and think about how SQL is processed, it should make sense to you why the SQL is not valid.
If you want to apply a filter condition such as:
trunc(max(RD.DATERECEIVED)) BETWEEN TO_DATE('01/08/2011','DD/MM/YYYY') AND TO_DATE('01/08/2011','DD/MM/YYYY')you should do it in a HAVING clause, not a where clause:
select ....
from ....
where ....
group by ....
having max(some_date) between this_date and that_date;Hope that helps,
-Mark
Maybe you are looking for
-
Precise working in Illustrator
When resizing an object to, for example 20 mm, ilustrator automatically changes the size to 19,756 mm. Why is this happening? And is their a way to turn this off? The same thing happens, when moving an object, it just snaps a bit off. I checked if I
-
Connecting MBP to Home Internet
This is a very basic question - we have a wireless router and Comcast broadband. We have several wireless PCs and one wired PC connected to the router. Will there be any problems or conflicts with the MBP using the wireless connection? This is the fi
-
Comparing vector/waveform scopes between two clips
Is there a way to bring up the scopes for two separate clips to compare them as one can do in Premiere? I use the 2-up function often to compare clips visually, but it just does not cut it for some corrections.
-
Look and feel master detail form
Hello i have difficulties at the time of trying to decorate a master detail form i have 2 blocks one is the master and the other is the detail the question is can i change the text item of the master which are in the same tab canvas that the detail t
-
Hi All, I try to pull data from SAP BW through SSIS 2008. I already applied all the configuration requirements in Microsoft paper. I think something else should be configured on SAP BW but i have no idea what. Error : SYSTEM_FALIUR with function RSB_