Clarification on using function in where clause of oracle sql query
I have an issue in regarding function using where clause of sql query..
We are facing performance issue while executing query, so in what ways to improve the performance of the query which i have posted below.
select col ,case when my_function(parameter)
from tab1 a ,tab2 b,tabl3 c
where a.column1=b.column2
and b.column3 =c.column6
and my_function(parameter)>0
Regards
Dinesh
Edited by: wild fire on May 18, 2012 4:15 PM
Dinesh,
remind that when you use a function in the where clause it normally will get started for each record in the table.
So your answer is two-fold:
1. make the function only start when needed by adding a function based index on the table (this will make inserts and updates slower)
2. make the function faster by adding the DETERMINISTIC clause if possible. this will make Oracle "cache" the result of the function.
Regards,
Richard
blog: http://blog.warp11.nl
twitter: @rhjmartens
If this question is answered, please mark the thread as closed and assign points where earned..
Similar Messages
-
Using function in where clause
I have created a function as follows
create or replace FUNCTION get_codes RETURN varchar2 IS
scodes varchar2(50) := 'A1,A2';
BEGIN
scodes := '('''||REPLACE(scodes,',',''',''')||''')';
return scodes;
END;
this function returns ('A1','A2')
now i want to use this in where clause, both below statements fetches no rows
select * from tablea where code in (select get_codes from dual);
select * from tablea where code in get_codes;
but the following will fetch rows
select * from tablea where code in ('A1','A2')
how to use function in where clause
ThanksHi,
The code that works:
where code in ('A1','A2')is testing whther code is either of two 2-character strings, A1 or A2.
The ones that don't work, such as:
where code in get_codes;are comparing code to one 9-character string: 'A1','A2', where characters 1, 4, 6 and 9 are single-quotes. (The function can only return one value.)
You can use dynamic SQL to embed that 9-character string in part of your query, where it will be interpreted as two 2-character strrings.
[Oracle Base|http://www.oracle-base.com/articles/misc/DynamicInLists.php] and AskTom have good pages on the subject of dynamic IN-lists.
Of you can use INSTR or LIKE:
where INSTR ( get_codes
, '''' || code || ''''
) > 0 -
How to dynamically update columns in a where clause to a SQL query in OSB?
Hi Gurus,
I have a requirement where in we need to dynamically update a where clause to a SQL query in OSB(11.1.1.6.0).
For example:
If the JCA sql string is "select * from emp where emp_id = 100 and emp_status ='Permanent'" now i want to change this where clause and the new query has to be like "select * from emp where emp_name like 'S%' and emp_dept like 'IT' ". basically we need to change the where clause dynamically.
We can also use "fn-bea:execute-sql()" in a xquery but I don't want to use this function as creates a new connection.
I have done some home work and found out --> as per the DOC "http://docs.oracle.com/cd/E23943_01/dev.1111/e15866/jca.htm#OSBDV943" section: "25.5.2 JCA Transport Configuration for Proxy and Business Services", when a business service is created by using JCA, we can see Interaction Spec Properties under JCA Transport Tab. This will have a property "SqlString' and we can over ride it. But I am unable to figure out how to over ride the value. I have tried by using Transport Headers activity but no luck. Please guide me how to achieve this?
Thanks in advance
SuryaI solved my problem.
In my header renderer, I simply added a line to set the text to the object value "label.setText( (String) value );" (where label is an instance of a JLabel.
Thank you to who took some time to think about it.
Marc -
How do I modify the WHERE clause in my SQL query?
This seems like such a straight-forward part of the report design, but I'm fairly new to Crystal Reports and I only have experience with modifying reports someone else has already written. In this particular case, I just need to modify the WHERE clause of the SQL query. I can select Show SQL Query and see what statement is being used to select data, but I can't find where to modify it since it's grayed out. I see how to change the selection criteria, parameters, grouping, etc...just not the WHERE clause. The report is linked to a database used for reporting with a table created and populated by a stored procedure. I don't need to modify the stored procedure because the data I want to filter by is currently in the table--I just don't know how to filter by what I need. Here's part of the query:
SELECT "rpt_dist"."startdate", "rpt_dist"."transtype", "rpt_dist"."laborcode", "rpt_dist"."crewid", "rpt_dist"."regularhrs" FROM "Reporting"."dbo"."rpt_dist" "rpt_dist"
WHERE (rpt_dist."transtype" <> 'WORK' AND rpt_dist."transtype" <> 'WMATL') AND rpt_dist."laborcode" LIKE 'S%' AND (rpt_dist."crewid" = 'HOUS' OR rpt_dist."crewid" = 'HOUS2' ...
I would like to add another crewid to the WHERE clause. Thanks for any input.1.Open the report in the crystal designer
2.Go to the field explorer(if hidden go to view menu->field explorer)
3.Rt. click on the database fields->choose database expert
4.Now you will see 2 columns-Available DataSource and Selected Tables
5.Rt. click on the object(ex.command) available in the Selected Tables column->Choose Edit command
6.A new Modify Command window will appear,here you can edit your SQL Query
I get to step 4 and I see the two columns including my database and the report table, but there is no command object available. If I right-click on my table, I can just view the Properties. ??
As for the other tip to modify the record selection: I don't see anywhere the other crewid values are set and if I add the one I'm missing, it doesn't modify the existing SQL Query and when I preview the report it throws off the results so that no data displays??
I'm using Crystal Reports 11.5 if that makes a difference. Thanks again. -
Regd. using functions in where clause
Hi All,
I need to apply a set of functions in sysdate and use that in a where clause to compare. My question is, will these functions on sysdate be executed for every record in the tables that I use? Will this have performance impact when i have millions of records returned by the select?
Below is the scenario:
Select * from table A inner join table B on A.c1 = B.c1 where
TO_NUMBER(TO_CHAR(TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, -1))),'YYYYMMDD')) BETWEEN Date1 and Date2
Regards,
Raj.D1005330 wrote:
I need to apply a set of functions in sysdate and use that in a where clause to compare. My question is, will these functions on sysdate be executed for every record in the tables that I use? Will this have performance impact when i have millions of records returned by the select?
Below is the scenario:
Select * from table A inner join table B on A.c1 = B.c1 where
TO_NUMBER(TO_CHAR(TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, -1))),'YYYYMMDD')) BETWEEN Date1 and Date2
Test it on a small data set - run a query and check the execution plan to see what the predicate section tells you.
Oracle OUGHT to be smart enough to recognise that you've got a constant that it need only calculate once. If not, then change the usage to read:
(select TO_NUMBER(TO_CHAR(TRUNC(LAST_DAY(ADD_MONTHS(SYSDATE, -1))),'YYYYMMDD')) from dual) BETWEEN Date1 and Date2Note, by the way, that 'constant between col1 and col2' is generally a tough one as far as efficiency is concerned; it translates to:
col1 <= constant
and col2 >= constantIn many cases this means oracle has to access a large volume of data (for one of the predicates) and then filter that data (with the other predicate). A typical damage limitation strategy is to create an index on the two columns, arrangin the column order to minimise the range scan on the first column.
Depending on your data patterns and the nature of the predicate there are alternative optimiisation strategies.
Regards
Jonathan Lewis -
How to avoid repeat where clause in oracle sql
Hi,
Please find my query below, I need a help to avoid duplication of **where** clause in my query.
In my below query, **JOIN** condition is same for both the queries and **WHERE** condition also same except this clause "and code.code_name="transaction_1"
In **IF ** condition only credit and debit is swapped on both queries, due to this **Credit and Debit** and this where clause "and code.code_name="transaction_1" I am duplicating the query. Can you please give some solution to avoid this duplication. I am using oracle 11g
select DAY as business_date,sum(amount) as AMOUNT, type_amnt as amount_type,test_code as code_seg
from
select table1_alias.date as DAY,code.code_numb as test_code,
CASE
WHEN qnty_item > 0 THEN 'credit'
ELSE 'debit'
END as type_amnt,
"25.55" as amount
from
code_table code,
table1 table1_alias
join table2 table2_alias on table1_alias.id = table2_alias.id
where
table1_alias.state="OK"
and table1_alias.type="R"
and code.code_type="Movie"
and code.code_name="transaction_1"
UNION ALL
select table1_alias.date as DAY,code.code_numb as test_code,
CASE
WHEN qnty_item > 0 THEN 'debit'
ELSE 'credit'
END as type_amnt,
"25.55" as amount
from
code_table code,
table1 table1_alias
join table2 table2_alias on table1_alias.id = table2_alias.id
where
table1_alias.state="OK"
and table1_alias.type="R"
and code.code_type="Movie"
and code.code_name="transaction_2"
group by DAY, test_code,type_amnt
Thanksuser10624672 wrote:
Hi,
Please find my query below, I need a help to avoid duplication of **where** clause in my query.
In my below query, **JOIN** condition is same for both the queries and **WHERE** condition also same except this clause "and code.code_name="transaction_1"
In **IF ** condition only credit and debit is swapped on both queries, due to this **Credit and Debit** and this where clause "and code.code_name="transaction_1" I am duplicating the query. Can you please give some solution to avoid this duplication. I am using oracle 11g
select DAY as business_date,sum(amount) as AMOUNT, type_amnt as amount_type,test_code as code_seg
from
select table1_alias.date as DAY,code.code_numb as test_code,
CASE
WHEN qnty_item > 0 THEN 'credit'
ELSE 'debit'
END as type_amnt,
"25.55" as amount
from
code_table code,
table1 table1_alias
join table2 table2_alias on table1_alias.id = table2_alias.id
where
table1_alias.state="OK"
and table1_alias.type="R"
and code.code_type="Movie"
and code.code_name="transaction_1"
UNION ALL
select table1_alias.date as DAY,code.code_numb as test_code,
CASE
WHEN qnty_item > 0 THEN 'debit'
ELSE 'credit'
END as type_amnt,
"25.55" as amount
from
code_table code,
table1 table1_alias
join table2 table2_alias on table1_alias.id = table2_alias.id
where
table1_alias.state="OK"
and table1_alias.type="R"
and code.code_type="Movie"
and code.code_name="transaction_2"
group by DAY, test_code,type_amnt
ThanksA very brief glance and it looks to me like the only difference between the 2 queries are
and code.code_name="transaction_1"In the first portion and
and code.code_name="transaction_2"So if that's all that is difference, you'd just want to use a single query (no union's) with
and code.code_name in ('transaction_1', 'transaction_2')Cheers, -
!! Getting error while using function in where clause
Hi,
I have created a function as below
create function find_cnt(n varchar2)
return number is
cnt number;
begin
execute immediate 'select count(1) from '||n into cnt;
return nvl(cnt,0);
end;
and when running the below select
select find_cnt(object_name),object_name from user_objects where object_type='TABLE' and find_cnt(object_name)=0
I getting
ERROR:
ORA-04044: procedure, function, package, or type is not allowed here
ORA-06512: at "SCOTT.FIND_CNT", line 5
can anyone help????????
thanks
HarishIn 11g you could simply do
SQL> select table_name, trim(column_value) cnt
from user_tables, xmltable(('count(ora:view("'||table_name||'"))'))
TABLE_NAME CNT
DEPT 4
BONUS 0
SALGRADE 5
DEMO_USERS 2
DEMO_CUSTOMERS 7
DEMO_ORDERS 10
DEMO_PRODUCT_INFO 10
DEMO_ORDER_ITEMS 16
DEMO_STATES 51
DEMO_PAGE_HIERARCHY 18
TABLE1 6
TABLE2 6
CREATE$JAVA$LOB$TABLE 0
CLICKS 1
T 0
EMP 14
PLAN_TABLE 2
17 rows selected. -
Can we use concatenate in where clause of a select query
I have a select query as follows....
SELECT ebeln ebelp belnr vgabe bwart DMBTR
FROM ekbe
INTO TABLE i_ekbe
FOR ALL ENTRIES IN i_blck
WHERE ebeln = i_blck-ebeln AND ebelp =
i_blck-ebelp.
Now i want to retrieve data from BKPF ..can i write a select query something like....
select * from BKPF into itab
FOR ALL ENTRIES IN i_ekbe
where awkey = ( conatenate i_ekbe-belnr i_ekbe-gjahr )
OR ELSE...is there any other way to link table ekbe and bseg ???Hi Poonam,
SELECT ebeln ebelp belnr vgabe bwart DMBTR
FROM ekbe
INTO TABLE i_ekbe
FOR ALL ENTRIES IN i_blck
WHERE ebeln = i_blck-ebeln
AND ebelp = i_blck-ebelp.
select *
from BKPF
into table itab
FOR ALL ENTRIES IN i_ekbe
where belnr = i_ekbe-belnr.
If u want to check with AWKEY concatenate into seperate field and then use to check in where condition.
data: lw_awkey(20) type c.
CONCATENATE i_ekbe-belnr i_ekbe-gjahr INTO lw_awkey.
select *
from BKPF
into table itab
FOR ALL ENTRIES IN i_ekbe
where awkey = lw_awkey
Best regards,
raam -
Strange errors when using user defined function in where clause
Hello,
I am having trouble with a function that, when used in the where clause of a select will cause an error if the first column selected is of type INTEGER. Not sure whether I am doing something wrong or whether this is a bug.
Here is a very simple test case:
create table test(
col1 integer not null,
col2 varchar(20) ascii default ''
insert into test values(1,'2011-03-15 05:00:00')
insert into test values(2,'2011-03-15 07:00:00')
CREATE FUNCTION BTR_TAG RETURNS VARCHAR AS
VAR ret VARCHAR(20);
SET ret='2011-03-15 06:00:00';
RETURN ret;
Select * from test where col2 >= BTR_TAG()
Select col1,col2 from test where col2 >= BTR_TAG()
=> Error in assignment;-3016 POS(1) Invalid numeric constant
Select '',* from test where col2 >= BTR_TAG()
Select col2,col1 from test where col2 >= BTR_TAG()
=> works as it should
MaxDB V 7.7.07.16 running on Windows Server 2003
I can replicated the test case above with Sql Studio and other ODBC based tools.
Thanks in advance,
Silke ArnswaldHello Siva,
sorry, but I don't understand your reply:
This is not right forum to posting this question.
You are from which module or working any 3rd party application.
MaxDB 7.7.07.16 is the community version of MaxDb,
we are not using it for SAP
and no 3rd party software is required to reproduce my problem,
Sql Studio or Database Studio will do.
Regards,
Silke Arnswald -
Can you use boolean function in where clause
Hi,
I have a boolean function. Is it possible to use it in where clause of query.
Eg;
is_prime(13) returns boolean
select 1 from dual where is_prime(13)What about something like this
Create or replace function boolret(id number) return boolean as
begin
If id <10 then
return true;
elsif id>10 and id<100 then
return false;
else
return null;
end if;
end;
1 declare
2 id_cat boolean;
3 begin
4 id_cat:= boolret(8);
5 dbms_output.put_line(id_cat);
6* end;
SQL> /
dbms_output.put_line(id_cat);
ERROR at line 5:
ORA-06550: line 5, column 2:
PLS-00306: wrong number or types of arguments in call to 'PUT_LINE'
ORA-06550: line 5, column 2:
PL/SQL: Statement ignored
It seems PL/Sql doesn't have any datatype like Boolean,But it handles Boolean like datatype.
Regards
Raj deep.A -
Using round off function in where clause
Hi All,
I'm trying to use round off function in where clause, I seek help in completing this script.
WITH CR_Details AS
(Select
request_id,
parent_request_id,
fcpt.user_concurrent_program_name Request_Name, phase_code, status_code,
round((fcr.actual_completion_date - fcr.actual_start_date),3) * 24 * 60 as Run_Time,
round(avg(round(to_number(actual_start_date - fcr.requested_start_date),3) * 1440),2) wait_time,
fu.User_Name Requestor,
fcr.argument_text parameters,
to_char (fcr.requested_start_date, 'MM/DD HH24:mi:SS') requested_start,
to_char(actual_start_date, 'MM/DD/YY HH24:mi:SS') ACT_START,
to_char(actual_completion_date, 'MM/DD/YY HH24:mi:SS') ACT_COMP,
fcr.completion_text
From
apps.fnd_concurrent_requests fcr,
apps.fnd_concurrent_programs fcp,
apps.fnd_concurrent_programs_tl fcpt,
apps.fnd_user fu
Where 1=1
and fcr.concurrent_program_id = fcp.concurrent_program_id
and fcp.concurrent_program_id = fcpt.concurrent_program_id
and fcr.program_application_id = fcp.application_id
and fcp.application_id = fcpt.application_id
and fcr.requested_by = fu.user_id
and fcpt.language = 'US'
and fcr.actual_start_date like sysdate )
select crd.*
from CR_Details crd
where Run_time <> '0'
AND wait_time <> '0'
GROUP BY
crd.request_id,
crd.parent_request_id,
crd.fcpt.user_concurrent_program_name,
crd.requested_start_date,
crd.User_Name,
crd.argument_text,
crd.actual_completion_date,
crd.actual_start_date,
crd.phase_code,
crd.status_code,
crd.resubmit_interval,
crd.completion_text,
crd.resubmit_interval,
crd.resubmit_interval_unit_code,
crd.description
Not sure about the GROUPBY function referencing the "crd." .Hi,
The best thing for you to do is start over. Start as small as possible, then take baby steps.
Pick one of the tables; fcr perhaps, and write a query that just uses that table, like this:
SELECT *
FROM apps.fnd_concurrent_requests fcr
WHERE fcr.actual_start_date >= TRUNC (SYSDATE)
AND fcr.actual_start_dt < TRUNC (SYSDATE) + 1
;(I think this is what you meant to do when you said "... LIKE SYSDATE".)
Make sure this little query gets credible results. When that tiny query is working perfectly, add another line or two. You can cut and paste code from what you posted, if that helps you.
If you get stuck, post the last version of your code that worked perfectly, and the latest version (only a line or two bigger) that has the problem. Describe what the problem is. If you get an error, post the complete error message. In any event, post CREATE TABLE and INSERT statements for all the tables and columns needed to run the query, and the results you want to get from that query.
When you post any code, format it, so that how the code looks on the screen gives some clues about how it is working.
When you post any formatted text on this site, type these 6 characters:
\(small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing.
If you going to use the AVG function in the sub-query, then you probably need to do a GROUP BY in the sub-query.
If you're not using any aggregate functions (like AVG) in the main query, then you probably don't want to do a GROUP BY in the main query.
I know this is a lot of work. I'm sorry. If there was an easier way, I wouldn't ask you to do all this. -
How can we use DECODE function in where clause.
Hi Guys,
I have to use DECODE function in where clause.
like below
select * from tab1,tab2
where a.tab1 = b.tab2
and decode(code, 'a','approved')
in this manner its not accepting?
Can any one help me on this or any other aproach?
Thanks
-LKR>
I am looking for to decode the actual db value something in different for my report.
like if A then Accepted
elseif R then Rejected
elseif D then Denied
these conditions I have to check in where clause.
>
what are you trying to do?
may be you are looking for
select * from tab1,tab2
where a.tab1 = b.tab2
and
(decode(:code, 'A','Accepted') = <table_column>
or
decode(:code, 'R','Rejected') = <table_column>
or
decode(:code, 'D','Denied') = <table_column>
) -
Date functions in WHERE clause? HELP
The following two queries are identical except for how I supply the date values in the where clause, yet the first query using the a custom my_date function runs 30x slower than the one using the TO_DATE() function. Both return DATE types...any reason for the difference?
SELECT * from outcomes
WHERE start_time >=fn_my_date('START_MONTH')
AND start_time < fn_my_date('END_MONTH')+1
-- This runs 30x faster--
SELECT * from outcomes
WHERE start_time >=TO_DATE('08/01/2001','MM/DD/YYYY')
AND start_time < TO_DATE('08/31/2001','MM/DD/YYYY')+1
On the flip side, I've also experienced queries running slower using the TO_DATE() function vs the LAST_DAY(sysdate) for equivalenet dates.
nullI haven't seen the message coming up when using LENGTH or SUBSTR, but every time I connect to a database or attempt to change my preferences (including the "NLS Parameters: Comp" preference), this appears.
You are attempting to set the preference you should be to switch this from ANSI to something else, but SQL Developer is ignoring the preference setting (which I think is a bug).
A way to set the NLS_COMP to something else is to use something like "alter session set nls_comp = BINARY;". Note that changing any preference after that appears to overwrite this and you need to do this for each new connection you start. -
Bad performance when calling a function in where clause
Hi All,
I have a performance problem when executing a query that contains a function call in my where clause.
I have a query with some joins and a where clause with some regular filters. But one of these filters is a function, and its input parameters are columns of the tables used in the query.
When I run it with only a few rows in the tables, it goes ok. But as the number of rows grows, performance falls geometrically, even when my where clause filters the result to only a few rows.
If I take the function call off of the where clause, then run the query and then call the function for each returned row, performance is ok. Even when the number of returned rows is big.
But I need the function call to be in the where clause, because I can't build a procedure to execute it.
Does anyone have any clue on how to improve performance?
Thanks,
RafaelYou have given very little information...
>
If I take the function call off of the where clause, then run the query and then call the function for each returned row, performance is ok. Even when the number of returned rows is big. Can you describe how you measured the performance for a big result set without the function? For example lets say there had been 10.000 rows returned (which is not really big, but it is astarting point). Did you see all 10.000 rows? A typical mistake is to execute the query in some tool like Oracle SQL Developer or TOAD and measure how fast the first couple of rows are returned. Not the performance of the full select.
As you can see from this little detail there are many questions that you need to address first before we can drill down to the root of your problem. Best way is to go through the thread that Centinul linked and provide all that information first. During the cause of that you might discover that you learn things on the way that help a lot for later tuning problems/approaches.
Edited by: Sven W. on Aug 17, 2009 5:16 PM -
Can't have aggregate function in WHERE clause clause
Dear all,
I've created object in BO XI 3.1 Designer with following criterias:
http://img4.imageshack.us/img4/833/20111201124314.th.jpg
It is a simple number - 1,2,3,4,5.
Now I need to use this object as a criteria for WHERE function in another object.
http://img607.imageshack.us/img607/1543/20111201124717.th.jpg
I receive an error "Can't have aggregate function in WHERE clause <clause>"
How can I overcome this?
P.S. I'm sorry in advance if such topic already exist - I didn't found one.
Edited by: Ashot Antonyan on Dec 1, 2011 9:50 AM
Edited by: Ashot Antonyan on Dec 1, 2011 9:51 AMHi,
You will have to use Sub query to achieve this. Give more details on what is available and what you need then i could help you out with the complete solution.
Thanks,
Ravichandra K
Maybe you are looking for
-
DW 5.5 uploading to wrong location
I have recently restored a site using the New process. The local and remote files were already in place. When I make a change, it uploads OK apparently, except that the file goes to the wrong place and is not seen when browsing. The site in questi
-
Ti G4 PB crashes when running Software Update
I just received a Titanium PowerBook G4 800Mhz used on eBay. Has 512MB ram, 100GB Hitachi 5400rpm hardrive insalled, airport card and came freshly formatted with 10.3 installed and a CD with system patches up to 10.3.9. I reformatted the hardrive and
-
Store workflow attachments in a content server
Hello Everyone, I am newbie to ABAP and This Forum. I have a requirement in which I have to store all workflow attachment in a content server. I think by changing storage type in oac0 and calling transaction oaor in workflow, I can do this. But I am
-
Reinstall max os error on disc 2
I have a MacBook Pro that I inherited from someone at work. They also gave me the Max OS X Discs (1 & 2), that they got with the computer. Max OS Version 10.4.9. They had configured the Mac to run Windows, So I had to repartition the HD before I c
-
HD VOlumes stuck in a network ???
I have been trying to get help with this for two days now with no luck. SO I am getting ready to just trash everything and start over . I have an external hd so I figureed I would copy the HD . I am using Deja VU and I noticed something. There is a f