case of condition in where clause
HelloI am a beginner in SQL, but according to my reading of the manual, this syntax should be acceptable. I'm using application express but tested also in Developer SQL and the conclusion that it fails with an error "invalid relational operator", with the line number pointing to the ELSE clause of the condition, but a number of column pointing to white space.
This is a select statement nested, but that shouldn't matter. The fragment in question is:
Select columns
RES
where res.villaid =: P605_VILLAID
and INSTR (: P604_RES_STATES, res.states). = 0
and (CASE: P604_EXCLUDE_ZERO)
WHEN 'Y' THEN ' res.rate > 0'
ELSE ' res.rate > = 0'
END)
and res. DEPARTDATE >: P605_STARTDATE
and res. ARRIVEDATE < =: P605_ENDDATE.
I hope that this puts ok shaped during the validation. The code is looking for bookings within a range of dates (which works very well when the other conditions are discussed), and should only output offset lines (nights) if the user asks for it in the variable of liaison P604_EXCLUDE_ZERO. There are probably other ways to go about this, but I'm too stubborn to renounce it. Well, not yet anyway.
Thanks and greetings
CS
select some columns
from res
where res.villaid = :p605_villaid
and instr (:p604_res_states, res.states) != 0
and sign (res.rate) >= case when :p604_exclude_zero = 'Y' then 1 else 0 end
and res.departdate > :p605_startdate
and res.arrivedate <= :p605_enddate
Tags: Database
Similar Questions
-
Tuning - using the CASE statement in the WHERE clause of the query
Hi all
My request has been changed to use a CASE statement in the WHERE clause to examine the data to some columns based on a parameter value. This modified request is made a full table and constantly running scan. Please suggest what can be done to improve its performance:
Query:
Description of the table: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;
(Number of lines: approx. > amount 600 000 000)
Explain PlanName 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)
Published by: Chaitanya on June 9, 2011 02:44SQL> 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)
Published by: Chaitanya on June 9, 2011 02:47When it is executed individually, MERGE LOGIC 1 and LOGIC of MERGE 2 take about ten for a daterange of 30 days data.
BUT FULL is to get the scores of APR - JUN, INCR becomes partitions for MAY so not both 30 days.
Are compare us like with like? -
Case statement in a WHERE clause
Gurus,
Im trying to avoid Union of several select statements using a CASE inside a WHERE clause. When the parameter is defined as "What's new" it is advisable to use a code and for "Update Items" another condition.
Having a problem with the following... I know that BOX in WHEREs instructions are allowed only can not make it work for this one.
Points for correct and helpful answers!and case when 'New Items' = 'xxx' --p_item_status then msi.creation_date = msi.last_update_date when 'Updated Items' = 'bbb' --p_item_status then msi.creation_date != msi.last_update_date else 1=1 end;
Published by: sreese on March 27, 2012 17:51Hello
The great thing about CASE expressions, is that they allow you to use a login IF-THEN-ELSE in the clause SELECT, the ORDER BY clause or anywhere else. The WHERE clause has its own way to IF-THEN-ELSE logic, so even if you can use a CASE expression in a clause WHERRE, it usually does not help anything. You can do somehting like this:
WHERE ( :p_item_status = 'New Items' AND msi.creation_date = msi.last_update_date ) OR ( :p_item_status = 'Updated Items' AND msi.creation_date != msi.last_update_date ) OR ( :p_item_status NOT IN ( 'New Items' , 'Updated Items' ) )
This guess: p_item_status is not NULL.
If: p_item_status can be NULL, and you want to include all the lines where it is, and then change the last condition toOR ( NVL (:p_item_status, 'OK') NOT IN ( 'New Items' , 'Updated Items' ) )
I hope that answers your question.
If not, post a small example of data (CREATE TABLE and INSERT, only relevant columns instructions), some values of the parameter and the expected results of these data for each value of the parameter.
Explain, using specific examples, how you get these results from these data.
Always tell what version of Oracle you are using. -
A CASE statement with additional where clause
Hi all
I need assistance in which this obligation clause
Table:-balance_table
Columns:-balance_type, balance_amount, balance_month, budget_name
balance_type column had given 'Real' OR 'Budget '.
Now I am trying to extract data such as: if: entered_month is Mar-2009 then before and including Mar-2009 will show real balance sheet Date and after Mar-2009 will show budget data.
It works fine, I need to add a condition more restrict the budget name, there are several budget_name in the table for balance_type = 'Budget '.
SELECT SUM (balance_amount), balance_type, balance_month
OF balance_table
WHERE balance_type =
(CASE
WHEN balance_month < =: entered_month
THEN 'real '.
ANOTHER 'Budget '.
END
)
AND budget_name = 'BUDGET1.
Balance_type GROUP, balance_month
Stated above is erroneous because ' AND budget_name = ' BUDGET1 "clause restricts the set of data."
Please help in contrcuting where clause 1) to sort the data according to Budget/actual and 2) for specific budgets, so budget_type = Budget
Thank you
BobinThat should do it.
SELECT SUM (balance_amount), balance_type, balance_month FROM balance_table WHERE (balance_type = 'Actual' and balance_month <= :entered_month ) or (balance_type = 'Budget' and balance_month > :entered_month and budget_name = :entered_budget_name ) GROUP BY balance_type, balance_month ORDER BY 2
See you soon
Sarma. -
Using a CASE statement in 'IN' where clause clause
Hello
I have a form that users see after they connect with a few items and they type or select values based on the element type. All reports in the application use these values of PAGE 1 in where clause to filter the lines.
One of these question is "Quarter". I have a group of radio buttons on the PAGE 1 on the P1_QTR point.
I need to provide users a way to take the last 4, last 3, last 2 or current quarter and I need to dynamically build a clause WHERE the interactive report based on the selection in the form.
I am trying to use the CASE as shown below and get the syntax error.
AND QTR to (when BOX: P1_QTR = 'CURRENT' then ("T4"))
When: P1_QTR = "LAST" then ("Q3")
When: P1_QTR = 'LAST TWO' then ('Q3, "Q4")
When: P1_QTR = 'LAST THREE' then ("Q2", "Q3,' T4 ')
another ("T1", "T2", "Q3,' T4 ')
END)
How can I achieve this?
Following a simple logic, try
and QTR to
(
Select 'T4' double where: P1_QTR <> 'LAST '.
Union of all the
Select 'Q3' to double where: P1_QTR <> "in PROCESS".
Union of all the
Select "Q2" double where: P1_QTR not in ('CURRENT', 'LAST', "LAST TWO")
Union of all the
Select "Q1" double where: P1_QTR not in ('CURRENT', 'LAST', 'LAST TWO', 'THREE LATEST')
)
-
Case instructions within a Where clause clause
Hello group,
I know this has been asked several times, but I do not enter simply to a tuition assistance box in a WHERE clause. So I need help:
My current WHERE the clause reads:
A16. FULL_DATE between (SELECT (TRUNC (SysDate - 8)) From Dual) and (select (TRUNC (SysDate - 2)) double)
However, I need to 'automate' a bit, based on the current time/day of the month. I need my instruction box to say:
(Case when to_char (sysdate-3, 'mm') <>to_char (sysdate, 'mm')
then the a16. FULL_DATE (between SELECT (trunc (ADD_MONTHS ((LAST_DAY(SysDate-3)),-1)+1) and (SELECT (add_months (trunc(SysDate-2)-1)) of double)))
Of another a16. FULL_DATE between (SELECT trunc (ADD_MONTHS ((LAST_DAY (SysDate)),-1)+1) From Dual) and (select (TRUNC (SysDate - 2)) From Dual)
However, I have an error on "Else". Can someone explain what is the problem and how to fix it? I tried both 'then' and 'Else' syntax and both will run individually. So I'm quite sure that he does not like my CASE statement in general.
In advance, thank you for your help.
Don
I can't tell what your business logic, so here's a simple example of an instruction box in the where clause:
SQL > select *.
2 double
3 where dummy = case when extracted (sysdate months) = 9 then 'W '.
4 Once extracted (sysdate months) = 10 then 'X '.
When 5 extract (month from sysdate) = 11 then 'Y '.
6 else 'Z'
7 end
8;D
-
X -
No output for report of XML editor using CASE/DECODE in a Where Clause
Hello
I have a requirement of the company to modify an existing report that has two input parameters,
-> p_statcode (closed status) which may have values "Y" or "n".
-> p_overdue (flag late), which can have values of "Y" or "n".
The flag late is a column evaluated with O/N values and it is evaluated as follows,
The requirement of user now is that they must be a third option for setting called p_overdue ALL,ONTF_MOD_VAL(NVL ( (TRUNC (SYSDATE) - (TO_DATE (oe_order_lines.attribute18, 'DD-MON-RRRR') + TO_NUMBER (fnd_lookup_values.meaning))), 0 )) overdue_flag
which by the way the output should include records with
p_statcode is p_statcode ELSE is N AND Y OR p_overdue p_overdue is N
In other words records with raising the Y and N for flag late must be returned regardless of the value given to the closed state.
Original where clause contained in the data definition file is as follows,
My modified code is the following,WHERE Closed_Status = nvl(:p_statcode,Closed_Status) AND overdue_flag = nvl(:p_overdue,overdue_flag)
ORWHERE 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)
Both approaches have the same problem.WHERE Closed_Status = NVL (:p_statcode, Closed_Status) AND overdue_flag = DECODE (:p_overdue, 'Y', 'Y', 'N', 'N',overdue_flag)
The output is in EXCEL format. The modified query works very well for p_overdue as Y or N but when p_overdue is passed as ALL he returned a blank EXCEL sheet with just exit report column headings.
Any help regarding, why is this the case? What's not in my approach?
Kind regards
Vishalunclear on p_overdue = ALL
P_overdue = ALL on what necessary values?try sth 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' values of "n".
If overdue_flag that in ('Y', ' don't) thenWHERE 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' )
-
case in PL/SQL where clause statement
- Hello
- I have a research procedure where the user can search on the city, street, zip code.
- I need meet the 6 different combinations as I don't know what value the user will pass.
- It should be checked if the user passes the value or not, and then look on values passed.
- But the procedure below is out.it the slightest mistake can be transformed with if-then-else, but case statement seems much cleaner in the code.
- procedure searchaddress (pc_town IN SEARCHADDRESS. CITY % TYPE,
pc_street IN SEARCHADDRESS. TYPICAL STREET %,
pc_postcode IN SEARCHADDRESS. POSTCODE % TYPE,
pResultSet to ref_cursor) as
Start
Open the pResultset for
Select searchaddress_pk from searchaddress
where
case
When pc_town is null then ((street = pc_street) and (ZipCode = pc_postcode))
When pc_street is null then ((town = pc_town) and (ZipCode = pc_postcode))
When pc_postcode is null then ((town = pc_town) and (street = pc_street))
When pc_town is null and pc_street is null then (postal code = pc_postcode)
When pc_street is null and pc_postcode is null then (city = pc_town)
When pc_town is null and pc_postcode is null then (street = pc_street)
end
end searchaddress;
Thank you
CenterB
A basic concept that is important to understand - sliders aren't 'sets of results' (sets of data in memory). A cursor is a series of executable steps (see plans run to cursor). It's like a program. An extraction run the program and output data. In general, which is repeated until the cursor (aka program) is no longer found the corresponding lines.
A ref cursor is a pointer or a handle for a such slider, passed to a caller, allowing the appellant to interface directly with this slider/program.
The slider more effective to create a search would be one without superfluous code and predicates and filters. Consider the following approach - a beefier PL/SQL procedure, do not try and play little tricks with SQL predicates in an attempt to create one (and probably not optimal) SQL.
(not tested/compiled code)
create or replace procedure SearchAddress( town IN SEARCHADDRESS.TOWN%TYPE, street IN SEARCHADDRESS.STREET%TYPE, postcode IN SEARCHADDRESS.POSTCODE%TYPE, refCur out ref_cursor ) is curHandle integer; res integer; searchSQL varchar2(1000); begin -- create base query searchSQL := 'select searchaddress_pk from searchaddress where 1 = 1 '; -- add dynamic predicates as needed if town is not null then searchSQL := searchSQL || 'and town = :town'; end if; if street is not null then searchSQL := searchSQL || ' and street = :street'; end if; if postcode is not null then searchSQL := searchSQL || ' and postcode = :postcode'; end if; -- create a DBMS_SQL cursor curHandle := DBMS_SQL.open_cursor; DBMS_SQL.parse( curHandle, searchSQL, DBMS_SQL.NATIVE ); -- bind the dynamic bind variables added as predicate values if town is not null then DBMS_SQL.Bind_Variable( curHandle, 'town', town ); end if; if street is not null then DBMS_SQL.Bind_Variable( curHandle, 'street', street ); end if; if postcode is not null then DBMS_SQL.Bind_Variable( curHandle, 'postcode', postcode ); end if; -- execute cursor (to create the cursor program) and pass it back as a ref cursor res := DBMS_SQL.Execute( curHandle ); refCur := DBMS_SQL.To_RefCursor( curHandle ); end;
-
Simple conditional SQL WHERE Clause with two Subselects
Hi SQL Experts,
I need some quick help with a query.
It is a ' select ' for a data source object repository phyiscal table OBI.
So, I can't put in PL/SQL or in stored procedures. I just need
have two conditions / selects different according to the user's role (this information comes
of the session).
The above does not work:-ORA00905. 00000 - 'lack the key word'
SELECT OFFICENO FROM orgunit
WHERE
BOX WHEN "SESSION_VARIABLE' LIKE '% globalmanager %' THEN
ASSIGNEDOFFICES =
(
SELECT DISTINCT ASSIGNEDOFFICES
FROM USERSTABLE INNER JOIN orgunit WE
OrgUnit. KEY = USERSTABLE. OFFICE
WHERE USERSTABLE. USERNAME ='VALUEOF (NQ_SESSION. THE USER)"
)
ON THE OTHER
OFFICENO =
(
SELECT DISTINCT USERSTABLE OFFICENO
INNER JOIN orgunit WE
OrgUnit. KEY = USERSTABLE. OFFICE
WHERE USERSTABLE. USERNAME ='VALUEOF (NQ_SESSION. THE USER)"
)
END;Can anyone help?
Hello
I can't tell what you want to do by looking at the code that do not do. Maybe:
SELECT officeno
For orgunit
WHERE (session_variable LIKE '% globalmanager %'
AND IN assignedofficies
(
SELECT assignedoffices
UserTable U1
JOIN orgunit o1 ON o1.officekey = u1.officekey
WHERE u1.username = ' VALUEOF (NQ_SESSION. THE USER)"
)
)
OR (NVL (session_variable
, '?'
) NOT LIKE '% globalmanager % '.
AND IN officeno
(
SELECT officeno
Of u2 usertable
JOIN orgunit o2 ON o2.officekey = u2.officekey
WHERE u2.username = ' VALUEOF (NQ_SESSION. THE USER)"
)
)
;
There might be a simpler and more efficient way in function your tables and your limit.
The condition u2.username = ' VALUEOF (NQ_SESSION. The USER) "almost certainly not what you really want.
.
Whenever you have any questions, post a small example data (CREATE TABLE and only relevant columns, INSERT statements) for all of the tables involved and also publish outcomes from these data.
Explain, using specific examples, how you get these results from these data.
Always say what version of Oracle you are using (for example, 11.2.0.2.0).See the FAQ forum: https://forums.oracle.com/message/9362002#9362002
-
Case statement in a where clause clause
Hi all
This is a query that works perfectly except when: P_value don't have any value the two result Y and N should show as a result.
I tried with a statement of NVL but it gives me an error. Someone can help me.
-----------------------------------
Select
ID
CASE
WHEN (colonne_1) > (column_2)
THEN 'Y '.
ANOTHER "N".
END 'Test '.
OF tabel_1
WHERE
(CASE
WHEN (colonne_1) > (column_2)
THEN 'Y '.
ANOTHER "N".
END
) =: P_value
---------------------------------When: P_value have no any value the two result Y and N should show as a result.
It is not fair
SELECT id, CASE WHEN (column_1) > (column_2) THEN 'Y' ELSE 'N' END "Test" FROM tabel_1 WHERE (CASE WHEN (column_1) > (column_2) THEN 'Y' ELSE 'N' END = :p_value OR :p_value IS NULL)
??
-
How to check this condition in where clause
WITH t1 AS (SELECT 1 empno, 'Sun' name,100 deptno, 'M' Gender FROM dual UNION ALL SELECT 2,'Gun',100 deptno, 'F' FROM dual UNION ALL SELECT 3, 'Run',50,'M' FROM dual UNION ALL SELECT 4, 'Nun',75,'F' FROM dual UNION ALL SELECT 5, 'Tun',25,NULL FROM dual) SELECT empno,name,deptno,gender FROM t1; I want to display those dept. data which is having Genders both 'M' and 'F',
You can use two ANDed 'exists' conditions...
... SELECT empno,name,deptno,gender FROM t1 t1o; where exists (select 'x' from t1 t1i where t1o.deptno = t1i.deptno and t1.gender = 'M') and exists (select 'x' from t1 t1i where t1o.deptno = t1i.deptno and t1.gender = 'F')
-
I need account condition in where clause.
Hi all
I have a data
Product ID AMT
1 100 A 1 100 B 1 100 C 1 100 D 2 25 A 2 40 E 2 55 F 3 50 B 3 50 A 3 50 C 3 50 G 4 12 H 4 13 E 4 14 A 4 15 I have I need following output
ID AMT Product 1 100 A 1 100 B 1 100 C 1 100 D 3 50 B 3 50 A 3 50 C 3 50 G
I tried after query, but it does not work
Select
ID,
AMT,
Product
t
Product ID, AMT Group,
having count (distinct ID) = count (distinct AMT)
It returns all the rows.
Help, please
with t as)
SELECT id,
AMT,
product,
County (separate amt) over (partition by id) cnt
of sample_data
)
SELECT id,
AMT,
product
t
where cnt = 1
order by id
/
AMT ID P
---------- ---------- -
1 100 A
1 100 B
1 100 C
1 100 D
3 50
3 50
3 50
3 508 selected lines.
SQL >
SY.
-
Result of conditional function where clause
create the table datatest
(number of primaryid,
Identification number,
power varchar2 (4).
alias varchar2 (15))
insert into values(1,100,'CNN','NEWS') datatest.
insert into values(2,100,'BBC','SPORTS') datatest.
insert into values(3,101,'CNN','INV') datatest
insert into values(4,101,'ABC','MON') datatest
insert into values(5,102,'BBC','REAL') datatest
insert into datatest values (6 103, 'NEC', "TVL")
I am looking for a query which returns lines with power CNN
If the CNN feed isn't here then return the line with power BBC
This is the result I'm looking for.
1 100, CNN, NEWS
3 101, CNN, INV
5 102, BBC, REAL
Thnx in advancecreate table datatest ( primaryid number, secondaryid number, feed varchar2(4), the_alias varchar2(15) ); begin insert into datatest values(1,100,'CNN','NEWS'); insert into datatest values(2,100,'BBC','SPORTS'); insert into datatest values(3,101,'CNN','INV'); insert into datatest values(4,101,'ABC','MON'); insert into datatest values(5,102,'BBC','REAL'); insert into datatest values (6,103,'NEC','TVL'); end; select * from ( select primaryid, secondaryid, feed, the_alias, row_number() over (partition by secondaryid order by decode(feed, 'CNN', 1, 'BBC', 2) asc) as rn from datatest where feed in ('CNN', 'BBC') ) where rn = 1
Would be a solution.
-
CASE of Condition causing Plan difference
Version
OptimizerSQL> SELECT * FROM v$version; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production PL/SQL Release 11.2.0.2.0 - Production CORE 11.2.0.2.0 Production TNS for Linux: Version 11.2.0.2.0 - Production NLSRTL Version 11.2.0.2.0 - Production 5 rows selected.
ProblemSQL> show parameter optimizer NAME TYPE VALUE ------------------------------------ ----------- ------------------------------ _optimizer_autostats_job boolean FALSE _optimizer_join_elimination_enabled boolean FALSE optimizer_capture_sql_plan_baselines boolean FALSE optimizer_dynamic_sampling integer 2 optimizer_features_enable string 11.2.0.2 optimizer_index_caching integer 0 optimizer_index_cost_adj integer 100 optimizer_mode string ALL_ROWS optimizer_secure_view_merging boolean FALSE optimizer_use_invisible_indexes boolean FALSE optimizer_use_pending_statistics boolean FALSE optimizer_use_sql_plan_baselines boolean TRUE
We have a system of providers that built the SQL to be sent to the database. These queries have the following generic structure for a condition in WHERE clause:
We have noticed different execution plans when the optimizer compares the numbers instead of varchar2. The examples below show that. In our case, this difference is an impact on the execution of a longer query plans effectively doubling buffer gets and leading to the execution times that are 2 to 4 times as worse.CASE WHEN <condition> THEN <table>.<column> END = '<value>'
Query 1
Query 2SQL> SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 1=1 THEN 'X' END = dummy; D - X 1 row selected. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT ---------------------------------------------------------------------------------------------- SQL_ID 6ghjubgpwpr61, child number 0 ------------------------------------- SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 1=1 THEN 'X' END = dummy Plan hash value: 272002086 --------------------------------------------------------------------------------------------- | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | Reads | --------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.02 | 2 | 2 | |* 1 | TABLE ACCESS FULL| DUAL | 1 | 1 | 1 |00:00:00.02 | 2 | 2 | --------------------------------------------------------------------------------------------- Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("DUMMY"='X')
To my eyes the status 'A' = 'A' is equivalent to the condition 1 = 1. How did in the case of the comparison digital Oracle allows to eliminate the case expression, but compared to the character he can't?SQL> SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 'A'='A' THEN 'X' END = dummy; D - X 1 row selected. SQL> SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY_CURSOR(null,null,'ALLSTATS LAST')); PLAN_TABLE_OUTPUT -------------------------------------------------------------------------------------------------- SQL_ID gcpwzksqr2w9n, child number 0 ------------------------------------- SELECT /*+gather_plan_statistics*/ * FROM DUAL WHERE CASE WHEN 'A'='A' THEN 'X' END = dummy Plan hash value: 272002086 ------------------------------------------------------------------------------------ | Id | Operation | Name | Starts | E-Rows | A-Rows | A-Time | Buffers | ------------------------------------------------------------------------------------ | 0 | SELECT STATEMENT | | 1 | | 1 |00:00:00.01 | 2 | |* 1 | TABLE ACCESS FULL| DUAL | 1 | 1 | 1 |00:00:00.01 | 2 | ------------------------------------------------------------------------------------ Predicate Information (identified by operation id): --------------------------------------------------- 1 - filter("DUMMY"=CASE WHEN ('A'='A') THEN 'X' END )
Thank you!Centinul wrote:
To my eyes the status 'A' = 'A' is equivalent to the condition 1 = 1.Well, question is Oracle looks like 'A' = 'A' as the string comparison. And the result of a string comparison is NLS charging. This is why it can not evaluate CASES at compile time.
SY.
-
several instructions box in where clause
Hello
I'm trying to create report filters using substitution variables in a case statement in a where clause clause. I have several instructions box running on the same column. I don't really know how to write it. Here's what I have so far but I know I'm going in the wrong direction.
where
i.compute_zone =
case
When: P14_zone is NOT NULL
then: P14_zone
of other i.compute_zone
end
AND
i.compute_zone =
case
When: P14_zone_2 is NOT NULL
then: P14_zone_2
other: P14_zone
end
AND
i.compute_zone =
case
When: P14_zone_3 is NOT NULL
then: P14_zone_3
of other i.compute_zone
end
AND
i.compute_zone =
case
When: P14_zone_4 is NOT NULL
then: P14_zone_4
of other i.compute_zone
end
any suggestions?
Thank you
MICAH
Hi, Micah,
User12611868-Oracle wrote:
Hello
I'm trying to create report filters using substitution variables in a case statement in a where clause clause. I have several instructions box running on the same column. I don't really know how to write it. Here's what I have so far but I know I'm going in the wrong direction.
where
i.compute_zone =
case
When: P14_zone is NOT NULL
then: P14_zone
of other i.compute_zone
end
AND
i.compute_zone =
case
When: P14_zone_2 is NOT NULL
then: P14_zone_2
other: P14_zone
end
AND
i.compute_zone =
case
When: P14_zone_3 is NOT NULL
then: P14_zone_3
of other i.compute_zone
end
AND
i.compute_zone =
case
When: P14_zone_4 is NOT NULL
then: P14_zone_4
of other i.compute_zone
end
any suggestions?
Thank you
MICAH
How get the desired results of your data depends on the desired results and your data. What do you do? (I can't tell just by looking at the aat code that do not do). After CREATE TABLE and INSERT statements for some sample data and a couple of sets of parameters (variables such as p14_zone) and the exact results that your choices in each set of parameters, given the same sample data.
Check out the Forum FAQ: Re: 2. How can I ask a question on the forums?
CASE expressions are generally not useful in a WHERE clause. CASE expressions are a convenient way to IF-THEN-ELSE logic of the places where you can't do anything other than (the SELECT clause), but WHERE the clauses allow IF-THEN-ELSE logic in any case
Maybe you want something like
WHERE MERGE (: p14_zone,: p14_zone_2,: p14_zone_3,: p14_zone_4) IS NULL
OR IN i.compute_zone (: p14_zone,: p14_zone_2,: p14_zone_3,: p14_zone_4)
It returns TRUE if all 4 parameters are set to NULL. If 1 or more of them are not NULL, then it will return TRUE if i.compute_zone is equal to one of them.
Maybe you are looking for
-
Just updated to 13.0 on my mac, but now I do not have tabs or see my open sites.
Have open several web pages, but cannot see one and when I close Firefox, it warns me that I have x number of sites open. I uninstalled and reinstalled and still the same problem
-
Problem with the Macbook pro 15 "light
Hello I have a macbook pro 15 "of 2011 and yesterday he gave me a failure when you use iMovie and now I'm not able to restart it more. When I was with iMovie, the screen became stripped horizontal screen and the computer crashed while I didn't have a
-
SSD 256 GB shows only 216 GB on MacBook
I had windows on my mac. I removed it with bootcamp. My ssd is normally 256 GB, now it shows that it is only 216 GB. Where is the rest?
-
HP PhotoSmart Prem 310 Series: Installation on PC Windows 8.1 HP solutions Center
My printer is a model 310 that I bought in 2011. The DVD accompanying installation supports Windows XP, Vista and 7. The version number of the DVD is 14.4.0 and I used it to try and install "HP Solution Center" on my new PC for Windows 8.1. What I
-
The button for an add-on I just downloaded did not appear, any ideas?
I just downloaded Reverse Image Search of Dmtr.org , but the button is not appearing to use it. Right-click on an image is not put on the shortcut menu. It is not disabled in the Add-ons Manager.