Rewriting a select statement containing a correlated subquery
Hi,
I would like to rewrite the statement below to improve it's performance. Is it possible?
*SELECT DISTINCT A.FIELD1
,A.FIELD2
,A.FIELD3
,A.FIELD4
,A.DATE_FIELD1
,(SELECT SUM(B.NUMBER_FIELD1)
FROM TABLE1 B
where B.FIELD1 = A.FIELD1
and B.FIELD2 = A.FIELD
and B.FIELD3 = A.FIELD
and B.FIELD4 = A.FIELD
and B.DATE_FIELD1 <= A.DATE_FIELD1
) as Total
FROM TABLE1 A*
The results should be a running total for a given "A.FIELD4" based on the date field "DATE_FIELD".
Many Thanks
Shouldn't the total for 13/JUL/09 be 0 instead of 3100 or am I missing something?
SQL> create table t as
2 select 'CP001' field1, '0004' field2, 'O' field3, '000000000000003' field4, to_date('01/JUL/09', 'dd/mon/yy') date_field1, 1550 number_field1 from dual union all
3 select 'CP001', '0004', 'O', '000000000000003', to_date('01/JUL/09', 'dd/mon/yy'), 1550 from dual union all
4 select 'CP001', '0004', 'O', '000000000000001', to_date('27/FEB/09', 'dd/mon/yy'), 1550 from dual union all
5 select 'CP001', '0004', 'O', '000000000000002', to_date('11/JUN/09', 'dd/mon/yy'), -1550 from dual union all
6 select 'CP001', '0004', 'O', '000000000000003', to_date('13/JUL/09', 'dd/mon/yy'), -1550 from dual union all
7 select 'CP001', '0004', 'O', '000000000000003', to_date('13/JUL/09', 'dd/mon/yy'), 1550 from dual union all
8 select 'CP001', '0004', 'O', '000000000000004', to_date('23/OCT/09', 'dd/mon/yy'), -3100 from dual union all
9 select 'CP001', '0004', 'O', '000000000000005', to_date('26/FEB/10', 'dd/mon/yy'), 1750 from dual union all
10 select 'CP001', '0004', 'O', '000000000000005', to_date('26/FEB/10', 'dd/mon/yy'), 1750 from dual;
Table created.
SQL> select * from t;
FIELD FIEL F FIELD4 DATE_FIELD1 NUMBER_FIELD1
CP001 0004 O 000000000000003 01-07-2009 00:00:00 1550
CP001 0004 O 000000000000003 01-07-2009 00:00:00 1550
CP001 0004 O 000000000000001 27-02-2009 00:00:00 1550
CP001 0004 O 000000000000002 11-06-2009 00:00:00 -1550
CP001 0004 O 000000000000003 13-07-2009 00:00:00 -1550
CP001 0004 O 000000000000003 13-07-2009 00:00:00 1550
CP001 0004 O 000000000000004 23-10-2009 00:00:00 -3100
CP001 0004 O 000000000000005 26-02-2010 00:00:00 1750
CP001 0004 O 000000000000005 26-02-2010 00:00:00 1750
9 rows selected.
SQL> -- your query (added only an extra order by):
SQL> select distinct
2 a.field1
3 , a.field2
4 , a.field3
5 , a.field4
6 , a.date_field1
7 , ( select sum(b.number_field1)
8 from t b
9 where b.field1 = a.field1
10 and b.field2 = a.field2
11 and b.field3 = a.field3
12 and b.field4 = a.field4
13 and b.date_field1 <= a.date_field1
14 ) as total
15 from t a
16 order by a.date_field1;
FIELD FIEL F FIELD4 DATE_FIELD1 TOTAL
CP001 0004 O 000000000000001 27-02-2009 00:00:00 1550
CP001 0004 O 000000000000002 11-06-2009 00:00:00 -1550
CP001 0004 O 000000000000003 01-07-2009 00:00:00 3100
CP001 0004 O 000000000000003 13-07-2009 00:00:00 3100
CP001 0004 O 000000000000004 23-10-2009 00:00:00 -3100
CP001 0004 O 000000000000005 26-02-2010 00:00:00 3500
6 rows selected.
SQL> -- an alternative, without analytics:
SQL> select a.field1
2 , a.field2
3 , a.field3
4 , a.field4
5 , a.date_field1
6 , sum(a.number_field1) total
7 from t a
8 group by a.field1
9 , a.field2
10 , a.field3
11 , a.field4
12 , a.date_field1
13 order by a.date_field1;
FIELD FIEL F FIELD4 DATE_FIELD1 TOTAL
CP001 0004 O 000000000000001 27-02-2009 00:00:00 1550
CP001 0004 O 000000000000002 11-06-2009 00:00:00 -1550
CP001 0004 O 000000000000003 01-07-2009 00:00:00 3100
CP001 0004 O 000000000000003 13-07-2009 00:00:00 0
CP001 0004 O 000000000000004 23-10-2009 00:00:00 -3100
CP001 0004 O 000000000000005 26-02-2010 00:00:00 3500
6 rows selected.
Similar Messages
-
How to create a mapping for a select statement containing DENSE_RANK( )?
Hi,
I want help with a select statement that I want to make a mapping of in OWB 11.1 g. Can anyone please tell me how is code can be incorporated in a mapping?
SELECT DISTINCT MAX (dimension_key) KEEP (DENSE_RANK FIRST ORDER BY day DESC) OVER (PARTITION BY calendar_week_name),
MAX (day) KEEP (DENSE_RANK FIRST ORDER BY DAY DESC) OVER (PARTITION BY calendar_week_name), calendar_week_end_date, calendar_week_number
FROM time_dim;I have been trying to use the Aggregator operator but I am not entirely sure how to go about it. Any help will be highly appreciated.
Thanks in advance,
Ann.Hi Ann
You can just use an EXPRESSION operator. Configure the mapping to be set based only code generation and operating mode.
You will have an expression output attribute for each one of your projected columns;
MAX (dimension_key) KEEP (DENSE_RANK FIRST ORDER BY day DESC) OVER (PARTITION BY calendar_week_name),
MAX (day) KEEP (DENSE_RANK FIRST ORDER BY DAY DESC) OVER (PARTITION BY calendar_week_name),
calendar_week_end_date,
calendar_week_number
Cheers
David -
Hi,
In crystal reports 10 is there a way to alter the select statement to include a subquery into the select statement. For example
select customer.lastname from customer;
to be
select customer.lastname , (select departmentname from dept where customer.dept_id= dept.dept_id) as "Customer_DeptName"
from customer;
I don't know how to do this in crystal but this can easily be done in toad or other sql query tool.
Please advise.
Thanks.
Tom.hi Tom,
i walk through how to create a sub select (using a command object instead of using tables) in this post here...
http://scn.sap.com/community/crystal-reports/blog/2012/07/11/show-all-sub-groups-and-a-summary-for-every-group
cheers,
jamie -
hi,
i got a select statement in my program as shown below
select * from ce4e001 where bukrs eq s_bukrs-low.
check s_kndnr.
check s_prctr.
move-corresponding ce4e001 to v_ce4e001.
append v_ce4e001.
endselect.
now i want to rewrite this select statement with using into table like
select * from ce4e001 into table v_ce4e001 where bukrs eq s_bukrs-low.
but my problem is
in the initial select statement they have used two check statements before appending
now how can i incorporate those two check statements in my new select statement
thanks
ramHi Ram,
Not sure why the check keywords where embedded within the select statments...it will have no impact if the selection variable where outside.
You could rewrite your new code as:
check s_kndnr.
check s_prctr.
select * from ce4e001 into table v_ce4e001 where bukrs eq s_bukrs-low.
Assign points if it works.
Thanks
-Saif -
How to model in OWB if you have a subquery in your select statement? (11.2)
Which operator (is it the Table operator) to use if I have a subquery as part of my select statement? (The way I do it works, but is not elegant. What I do is create a table for the subquery and than join that with the other sources to point to my target.) But, would appreciate the best way with OWB's features.
Here is the entire SQL (including the subquery):
SELECT to_numbe (null), course_id
at.book, lp.NAME,
(select b.pricing from qp_pricing_attributes b
where b.list_id = ll.list_id and b.product = at.product) sign,
ll.operand AS price, lhb.comments
FROM
pricing_attribs at,
list_lines ll,
list_h lp,
list_b lhb
WHERE 1 = 1
and ll.list_line_id = atrib.list_line_id
AND ll.list_header_id = lp.list_header_id
AND lp.list_header_id = lhb.list_header_id
Thanks you.Hi
Doesn't need to be a table in the target. Let's take a very simple example, let's say you wanted to do the following;
select ename,(select dname from dept d where d.deptno=e.deptno) from emp e
Then DEPT is your lookup table and EMP is your driving table.
1. Add EMP on to the canvas.
2. Add in lookup operator
3. Bind lookup to DEPT
4. Hit finish
5. Map EMP.DEPT to DEPT.INGRP1 (the lookup operator)
6. Edit lookup operator, on Lookup Conditions tab set DEPTNO for lookup column, and DEPTNO for input attribute
7. Lookup complete now
You can add in a target table operator and map from the source EMP table and the output attributes of the lookup operator. you can change step 4 to carry on through wizard and define lookup, but I have chosen to do 5, to automatically get the names and datatypes of the inputs. There are lot of other options now in 11gR2 in the lookup.
Hope this makes sense.
Cheers
David -
Executing a stored procedure containing multiple Select statements
Post Author: Beverly
CA Forum: General
I am using Crystal 10.0 against a MS SQL 2000 server.
I am trying to create a report based on a stored procedure that contains multiple select statements. The sp requires a single parameter (Claim number) and contains 17 Select statements that produce results.
I am able to use the Add command and execute the sp with the parameter, but I am only getting the results of the first select statement in the sp back in my data set. Is there a way to have the data from each Select statement returned to my report?
I have used Crystal for a while, but pretty much for straight-forward reporting. I am familiar with the basics of SQL.
I would appreciate any help anyone can offer.
Thanks.Post Author: BISoftware
CA Forum: General
I believe Crystal Reports can only handle one recordset at a time, which means it can only handle a single select statement. The only way I can see around this would be to break up your stored procedure into multiple stored procedures, so that each only contains a single select statement. Then, use subreports to report on each individual sp. Hope this helps. - Davewww.BusinessSoftwareResource.com -
Sql Error in Select statement when doing subquery
Hi,
I am trying to see what the error is in the subquery part of the select statement.
Subquery should be fetching the safety_stock_quantity based on the MAX(effectivity_date).
Any suggestions?
SELECT kbn.last_update_date,itm.segment1,itm.description,kbn.kanban_card_number,kbn.kanban_size,
(SELECT msc.safety_stock_quantity
FROM mtl_safety_stocks msc
WHERE msc.effectivity_date = (select MAX(msc2.effectivity_date)
from mtl_safety_stocks msc2
where msc2.inventory_item_id = itm.inventory_item_id
and msc2.organization_id = itm.organization_id)
AND msc.inventory_item_id = itm.inventory_item_id
AND msc.organization_id = itm.organization_id
FROM mtl_system_items_b itm
,mtl_onhand_quantities_detail moqd
,mtl_safety_stocks msc
,mtl_kanban_card_activity kbn
WHERE itm.inventory_item_id = kbn.inventory_item_id
AND itm.organization_id = kbn.organization_id
AND itm.inventory_item_id = moqd.inventory_item_id
AND itm.organization_id = moqd.organization_id
AND moqd.subinventory_code = kbn.source_subinventory
AND kbn.card_status = 1
AND kbn.supply_status = 5
AND msc.inventory_item_id = itm.inventory_item_id
AND msc.organization_id = itm.organization_id
GROUP BY
kbn.last_update_date,itm.segment1,itm.description,kbn.kanban_card_number,kbn.kanban_size;
Thanks
PravnHi, Pravn,
Remember the ABC's of GROUP BY:
When you use a GROUP BY clause and/or an aggregate fucntion, then every item in the SELECT clause must be:
(A) an <b>A</b>ggregate function,
(B) one of the "group <b>B</b>y" expressions,
(C) a <b>C</b>onstant, or
(D) something that <b>D</b>epends entirely on the above. (For example, if you "GROUP BY TRUNC(dt)", you can "SELECT TO_CHAR (TRUNC(dt), 'Mon-DD')").
There's a GROUP BY clause in your main query, so every item in the main SELECT clause must be one of the above. The last item, the unnamed scalar sub-query, is none of the above.
How can you fix this problem? That depends on your data, the results you want, and perhaps on your Oracle version. If you'd like help, post a little sample data (CREATE TABLE and INSERT statements, relevant columns only) from all tables involved. 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.
You may have noticed that this site normally doesn't display multiple spaces in a row.
Whenever you post formatted text (including, but limited to, actual code) on this site, type these 6 characters:
\(small letters only, inside curly brackets) before and after each section of formatted text, to preserve spacing. -
Subquery in IN clause of an select statement
Hi friends,
The Subquery in IN clause of an select statement take long time , is there any alternate ??
>select * from oudata.SURVEY_USER_ANSWERS
>where user_id in (select user_id from oudata.SURVEY_USERS where trunc(course_start_date) <'01-Jun-2007');
thnaks,
raj
Edited by: infant_raj on May 28, 2009 12:09 AMinfant_raj wrote:
Hi friends,
The Subquery in IN clause of an select statement take long time , is there any alternate ??
select * from oudata.SURVEY_USER_ANSWERS
where user_id in (select user_id from oudata.SURVEY_USERS where trunc(course_start_date) <'01-Jun-2007');
No database version specified?
No table structures/indexes given?
No indication of the cardinality, selectivity, skew of the data being queried.
Have you got a function based index for "trunc(course_start_date)"?
Why are you not specifying your comparison date as a DATE datatype rather than relying on implicit conversion? i.e. it should be "to_date('01-Jun-2007','DD-MON-YYYY')"
Have statistics been gathered on the data
[How to post a SQL statement tuning request|http://forums.oracle.com/forums/thread.jspa?threadID=863295&tstart=0]
[When your query takes too long...|http://forums.oracle.com/forums/thread.jspa?messageID=1812597#1812597] -
Performance of using a Select For Update vs a correlated subquery
I was wondering wether or not it is more effecient to use the
Select ... For Update (with a cursor etc.) versus a correlated
subquery.
I can accomplish the same thing with either however performance
at our site is an issue.Use select for update cursor as that is faster as it updates
based on the rowid. One thing to keep in mind is that rowid is
session specific and the rows to be updated get locked so that
nobody else can update them till the lock is released. I have
had very good performance results with these cursors.
Good luck !
Sudha -
USING SUBQUERY IN SELECT STATEMENT
I am looking at reusing the results of a first query in a second select statement.
I have a first table "ACTIVE_FIELDS" in which I maintain the columns I want to query.
Table name ACTIVE_FIELDS
Field - Status
CODE - ACTIVE
DESCRIPTION - ACTIVE
NAME - INACTIVE
So I get the list of active fields by doing :
SELECT FIELD FROM ACTIVE_FIELDS WHERE STATUS=ACTIVE
It gives me : Code and Description.
I have then a second table MATERIAL with 3 columns CODE, DESCRIPTION and NAME.
I am looking at doing a query against MATERIAL table as follows
SELECT (SELECT FIELD FROM ACTIVE_FIELDS WHERE STATUS=ACTIVE) from MATERIAL and I expect to only get columns CODE and DESCRIPTION in the result.
If I want to add the NAME field in the result of my query, I just have to change status of NAME field in the eh ACTIVE_FIELDS table..
Can anybody help me with the exact syntax, I must miss a function to convert the result of the first query..that data model looks suspiciously like an attribute-value generic model, thus the need for that funky sql.
read this thread.
Re: SIMPLE Database Design Problem ! -
Plsql procedure containing select statement to fill page items
I would like to fill items :P200_A and :P200_B and so on
with the result of a SELECT which depends on the different values of many select lists.
E.G. :P200_list_alpha with the list of values
STATIC:less than 10;less,equal than 10;equal,above 10;above,indifferent;indiff
:P200_list_beta with the list of values
STATIC:active;active,passiv;passiv,excluded;excluded
How do I write the select statement ? I think it has to be executed in an anonymous PLSQL Procedure (after submit).
What is a convenient way to write the select statement ?
I could imagine to use lots of IF , ELSIF, ELSE statements and in each branch (here 12 ) the whole/complet SELECT statement is written.
How to solve this problem in an elegant way ?
In my opinion the CASE statement could be helpful, but how to use it in the WHERE clause with this nested conditions ?I think I got it:
SELECT col1, col2, col3, ...
INTO :P200_A , :P200_B , ....
FROM mytable_1, mytable_2
WHERE mytable_1.col1 = mytable_2.col1
AND (
CASE
WHEN :P200_LIST_ALPHA = 'less' AND NVL(TO_COL_WITH_ALPHA, 0) < 10 THEN 1
WHEN :P200_LIST_ALPHA = 'equal' AND NVL(TO_COL_WITH_ALPHA, 0) = 10 THEN 1
WHEN :P200_LIST_ALPHA = 'above' AND NVL(TO_COL_WITH_ALPHA, 0) > 10 THEN 1
WHEN :P200_LIST_ALPHA = 'indiff' THEN 1
ELSE 0
END = 1 )
AND
( CASE
WHEN :P200_LIST_BETA = 'active' AND TO_COL_WITH_BETA IN ( 'a', 'A', 'akt', 'AKT' ) THEN 1
WHEN :P200_LIST_BETA = 'passive' AND TO_COL_WITH_BETA IN ( 'p', 'P' ) THEN 1
WHEN :P200_LIST_BETA = 'excluded' AND TO_COL_WITH_BETA = 'X' THEN 1
ELSE 0
END = 1 )
;Edited by: wucis on Oct 24, 2011 4:09 PM -
SELECT statement comparing 2 fields in a table.
Hi,
Can someone help me out in making a efficient SELECT statement for the follwing requirement.
Say, I want to select all the records from a database table where the field, PLANT is equal to field SALESORG in the table (i.e., when both fields are equal select that record).
Thanks & regards,
SreeHello,
I think this is the answer to your question... if you explain a bit more we can formulate a query.
Subquery
Variants:
1. ( select )
2. ALL ( select )
3. ANY ( select )
4. SOME ( select )
Effect
A subquery is a SELECT statement select that occurs within a
SELECT,
OPEN CURSOR,
UPDATE, or
DELETE statement
in the WHERE clause or HAVING clause, to check whether data from database tables or views meets certain criteria.
Subqueries have a restricted syntax in comparison to the normal SELECT statement:
SELECT result FROM source [WHERE where] [GROUP BY fields] [HAVING having].
Variant 1
( select )
If the subquery returns a single value, you can use any relational operator except LIKE and BETWEEN.
Example
Selecting the flights with the most passengers:
DATA: WA TYPE SFLIGHT.
SELECT * FROM SFLIGHT
INTO WA
WHERE SEATSOCC = ( SELECT MAX( SEATSOCC ) FROM SFLIGHT ).
WRITE: / WA-CARRID, WA-CONNID, WA-FLDATE.
ENDSELECT.
Note
If you use a subquery with a relational operator instead of EXISTS, you may only specify one column in the SELECT clause. This can be either a field from the database table or an aggregate expression. Subqueries of this kind are referred to as scalar subqueries.
Variant 2
ALL ( select )
If the subquery returns several lines, each containing one value, you specify that the comparison should apply for all of the values it returns.
Example
This example shows how to use ALL. It displays a list of the customer IDs of the customer (or customers) who have made the most bookings:
DATA: ID TYPE SBOOK-CUSTOMID, CNT TYPE I.
SELECT CUSTOMID COUNT( * ) AS C FROM SBOOK
INTO (ID, CNT)
GROUP BY CUSTOMID
HAVING COUNT( * ) >=
ALL ( SELECT COUNT( * ) FROM SBOOK GROUP BY CUSTOMID ).
WRITE: / ID, CNT.
ENDSELECT.
Variant 3
ANY ( select )
Variant 4
SOME ( select )
If the subquery returns several lines each containing one value, this variant specifies that the comparison should apply to at least one of the values returned. The IN operator is the same as the combination = ANY.
&ABAP_HINT
If you use a subquery with the EXISTS operator, the expression is true if the subquery selects at least one line. You can useuse * in the SELECT clause of subqueries that use EXISTS.
Example
Selecting all flights from Frankfurt to New York between 1.1.1999 and 31.3.1999 that are not yet full:
DATA: WA_SFLIGHT TYPE SFLIGHT.
SELECT * FROM SFLIGHT AS F INTO WA_SFLIGHT
WHERE SEATSOCC < F~SEATSMAX
AND EXISTS ( SELECT * FROM SPFLI
WHERE CARRID = F~CARRID
AND CONNID = F~CONNID
AND CITYFROM = 'FRANKFURT'
AND CITYTO = 'NEW YORK' )
AND FLDATE BETWEEN '19990101' AND '19990331'.
WRITE: / WA_SFLIGHT-CARRID, WA_SFLIGHT-CONNID,
WA_SFLIGHT-FLDATE.
ENDSELECT.
Subqueries such as the one in this example, in which the WHERE clause uses fields from the main query, are known as correlated subqueries. Subqueries can be nested, and a given subquery may contain any fields from other, hierarchically-superior subqueries.
In a correlated subquery, the subquery is executed for each line r returned by the main query. In the above example, the main query finds all flights in table SFLIGHT that are not full and that have a date that meets the selection criterion. The statement then performs the subquery for each of the records returned by the main query, using the corresponding values of CARRID and CONNID, to check whether the relevant flight operates between Frankfurt and New York.
Additional help
Subqueries -
JDOQL Correlated Subquery - Bad SQL
Hi,
When I execute a JDOQL correlated subquery, the generated SQL is either
invalid or incorrect. Exactly what happens depends on the exact query, and
on the target database type, but I believe it all stems from the same
problem, which has to do with table aliasing.
If you need further details to reproduce this, please let me know. I'll be
glad to help in any way I can to get this situation remedied quickly, as I
am depending on this functionality. I have a test application to
demonstrate the problem.
I'm using Kodo 3.3.3 and application identity.
Paul Mogren
CommerceHubFor the record, this is in part due to a bug in Kodo's SQL92 joining.
See http://bugzilla.solarmetric.com/show_bug.cgi?id=1156
-Patrick
Paul Mogren wrote:
Certainly... Here's a simple example using Microsoft's JDBC Driver for SQL
Server 2000, and kodo.jdbc.sql.SQLServerDictionary, which produces invalid
SQL.
The query:
pm.newQuery(Container.class,
"(select from Entry entry where entries.contains(entry) &&
entry.containedId != 1).isEmpty()");
The classes:
class Contained {
private int id; //pk
class Container {
private int id; //pk
private Set entries = new HashSet(); //<Entry>
class Entry {
private int containerId; //pk
private int containedId; //pk
private Container container; //persistent-redundant
private Contained contained; //persistent-redundant
The result:
Incorrect syntax near the keyword 'WHERE'. {prepstmnt 31598780 SELECT
t0.container_id, t0.lock FROM WHERE (NOT EXISTS (SELECT DISTINCT
t2.contained_id, t2.container_id FROM dbo.entry t2 WHERE (t1.contained_id
= t2.contained_id AND t1.container_id = t2.container_id AND
t2.contained_id <> ?) AND t0.container_id = t1.container_id))
[params=(int) 1]} [code=156, state=HY000]
Patrick Linskey wrote:
Hi Paul,
Kodo's correlated subquery support does have some known limitations. Can
you post a sample JDOQL statement + corresponding SQL statement?
-Patrick
Paul Mogren wrote:
Hi,
When I execute a JDOQL correlated subquery, the generated SQL is either
invalid or incorrect. Exactly what happens depends on the exact query, and
on the target database type, but I believe it all stems from the same
problem, which has to do with table aliasing.
If you need further details to reproduce this, please let me know. I'll be
glad to help in any way I can to get this situation remedied quickly, as I
am depending on this functionality. I have a test application to
demonstrate the problem.
I'm using Kodo 3.3.3 and application identity.
Paul Mogren
CommerceHub -
Top n Analysis using correlated subquery
Please explain this query. It is doing top n analysis using correlated subquery. I need explaination of execution of this query.
Select distinct a.sal
From emp a
where 1=(select count ( distinct b.sal) from emp b
where a.sal <=b.sal)
Thanks in advanceTry breaking the query down and rewriting it in order to follow the logic;
SQL> --
SQL> -- Start by getting each salary from emp along with a count of all salaries in emp
SQL> --
SQL> select a.sal,
(select count (distinct b.sal) from scott.emp b ) count_sal
from scott.emp a
order by 1 desc
SAL COUNT_SAL
5000 12
3000 12
3000 12
2975 12
2850 12
2450 12
1600 12
1500 12
1300 12
1250 12
1250 12
1100 12
950 12
800 12
14 rows selected.
SQL> --
SQL> --Add a condition to the count for only salaries below or equal to the current salarySQL> --
SQL> select a.sal,
(select count (distinct b.sal) from scott.emp b where a.sal <=b.sal) rank_sal
from scott.emp a
order by 1 desc
SAL RANK_SAL
5000 1
3000 2
3000 2
2975 3
2850 4
2450 5
1600 6
1500 7
1300 8
1250 9
1250 9
1100 10
950 11
800 12
14 rows selected.
SQL> --
SQL> -- Add a condition to only pick the nth highest salary
SQL> --
SQL> select a.sal,
(select count (distinct b.sal) from scott.emp b where a.sal <=b.sal) rank_sal
from scott.emp a
where (select count (distinct b.sal) from scott.emp b where a.sal <=b.sal) = 4
SAL RANK_SAL
2850 4
1 row selected.Hope this helps. -
SQL Bug in "Minus" in correlated subquery presence of index
(Oracle Database 11g Release 11.2.0.1.0)
Below, there is a small example that shows the bug. Further below,
there are some more comments.
drop table Country;
create table Country
(code VARCHAR2(4) constraint countrykey PRIMARY KEY,
name VARCHAR2(35));
-- if the key constraint is not given, the bug does not occur
drop table City;
create table City
(name VARCHAR2(35),
country VARCHAR2(4),
population number);
drop table Locatedon;
create table Locatedon
(city VARCHAR2(35),
country VARCHAR2(4),
island VARCHAR2(35));
insert into country values('E','Spain');
insert into country values('F','France');
insert into country values('S','Sweden');
insert into country values('GB','Sweden');
insert into city values('Ajaccio','F',53500);
insert into city values('Paris','F',2152423);
insert into city values('Palma','E',322008);
insert into city values('Madrid','E',3041101);
insert into city values('Stockholm','S',711119);
insert into city values('London','GB',6967500);
insert into locatedon values('Ajaccio','F','Corse');
insert into locatedon values('Palma','E','Mallorca');
insert into locatedon values('London','GB','Great Britain');
-- all countries that have a city that is not located on
-- some island: should be E, F, S.
Select c.name
From country c
Where exists
((Select name
From city
Where city.country=c.code)
minus
(Select city
From locatedon
Where locatedon.country=c.code)
-- wrong answer: only Sweden; Spain and France not in the answer!
select distinct country from
((Select name, country
From city)
minus
(Select city, country
From locatedon)
-- correct answer: E, F, S
Comments:
The bug has been found by students in our SQL course.
Using a larger database from that course, the bug can be reproduced
(same queries as above) at
http://www.semwebtech.org/sqlfrontend/
(wrong: 142 answers, correct: 154 answers)
During reducing it to a simple sample, there were some interesting
observations: trying with smaller and simpler tables (without the keys)
and synthetic data, the bug did not occur immediately. When
restating the query after about one day, the bug occurred. Obviously,
Oracle creates some index on its own in course of its internal
optimization that (or more exactly, its usage) exhibits the bug. The
query plan (showed in SQL Developer) was the same before and after.
WolfgangThere's a typo in the test data - GB should presumably not be in Sweden. However....
the bug did not occur immediatelyIt's possible. But what would have almost certainly happened is that the execution plan DID change at some point. There are various reasons why it might not be immediate.
Obviously, Oracle creates some index on its own in course of its internal optimizationFar from obvious, what are you on about?
The query plan was the same before and afterBet you it wasn't.
A clear illustration of the issue and indication that it must be a bug is below.
Simply by hinting a different access method, we can change the result. Therefore, bug.
See [url http://support.oracle.com]Oracle Support and search for "wrong results".
Please raise with Oracle Support to get confirmation of bug.
There have been so many wrong results bugs recently, it's getting ridiculous.
It's a real issue, IMHO.
If you can't trust the DB to get your data right....
Note that the query plan is very much NOT the same and it is the difference in query plan which s that is the root cause of the bug.
SQL> 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
SQL> SELECT c.name
2 FROM country1 c
3 WHERE exists ((SELECT name
4 FROM city1
5 WHERE city1.country=c.code)
6 MINUS
7 (SELECT city
8 FROM locatedon1
9 WHERE locatedon1.country=c.code));
NAME
Sweden
SQL> SELECT /*+ full(c) */
2 c.name
3 FROM country1 c
4 WHERE exists ((SELECT name
5 FROM city1
6 WHERE city1.country=c.code)
7 MINUS
8 (SELECT city
9 FROM locatedon1
10 WHERE locatedon1.country=c.code));
NAME
Spain
France
Sweden
SQL> explain plan for
2 SELECT c.name
3 FROM country1 c
4 WHERE exists ((SELECT name
5 FROM city1
6 WHERE city1.country=c.code)
7 MINUS
8 (SELECT city
9 FROM locatedon1
10 WHERE locatedon1.country=c.code));
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 156929629
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 27 | 12 (25)| 00:00:01 |
| 1 | NESTED LOOPS | | | | | |
| 2 | NESTED LOOPS | | 1 | 27 | 12 (25)| 00:00:01 |
| 3 | VIEW | VW_SQ_1 | 6 | 24 | 10 (20)| 00:00:01 |
| 4 | MINUS | | | | | |
| 5 | SORT UNIQUE | | 6 | 138 | | |
| 6 | TABLE ACCESS FULL | CITY1 | 6 | 138 | 4 (0)| 00:00:01 |
| 7 | SORT UNIQUE | | 3 | 69 | | |
| 8 | TABLE ACCESS FULL | LOCATEDON1 | 3 | 69 | 4 (0)| 00:00:01 |
|* 9 | INDEX UNIQUE SCAN | COUNTRYKEY | 1 | | 0 (0)| 00:00:01 |
| 10 | TABLE ACCESS BY INDEX ROWID| COUNTRY1 | 1 | 23 | 1 (0)| 00:00:01 |
Predicate Information (identified by operation id):
9 - access("VW_COL_1"="C"."CODE")
Note
- dynamic sampling used for this statement (level=4)
26 rows selected.
SQL> explain plan for
2 SELECT /*+ full(c) */
3 c.name
4 FROM country1 c
5 WHERE exists ((SELECT name
6 FROM city1
7 WHERE city1.country=c.code)
8 MINUS
9 (SELECT city
10 FROM locatedon1
11 WHERE locatedon1.country=c.code));
Explained.
SQL> select * from table(dbms_xplan.display);
PLAN_TABLE_OUTPUT
Plan hash value: 1378726376
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 1 | 23 | 14 (15)| 00:00:01 |
|* 1 | FILTER | | | | | |
| 2 | TABLE ACCESS FULL | COUNTRY1 | 4 | 92 | 4 (0)| 00:00:01 |
| 3 | MINUS | | | | | |
| 4 | SORT UNIQUE | | 1 | 23 | 5 (20)| 00:00:01 |
|* 5 | TABLE ACCESS FULL| CITY1 | 1 | 23 | 4 (0)| 00:00:01 |
| 6 | SORT UNIQUE | | 1 | 23 | 5 (20)| 00:00:01 |
|* 7 | TABLE ACCESS FULL| LOCATEDON1 | 1 | 23 | 4 (0)| 00:00:01 |
Predicate Information (identified by operation id):
1 - filter( EXISTS ( (SELECT "NAME" FROM "CITY1" "CITY1" WHERE
"CITY1"."COUNTRY"=:B1)MINUS (SELECT "CITY" FROM "LOCATEDON1" "LOCATEDON1"
WHERE "LOCATEDON1"."COUNTRY"=:B2)))
5 - filter("CITY1"."COUNTRY"=:B1)
7 - filter("LOCATEDON1"."COUNTRY"=:B1)
Note
- dynamic sampling used for this statement (level=4)
27 rows selected.Just to show that it's related to query transformation:
SQL> SELECT /*+
2 no_query_transformation
3 */
4 c.name
5 FROM country1 c
6 WHERE exists ((SELECT name
7 FROM city1
8 WHERE city1.country=c.code)
9 MINUS
10 (SELECT city
11 FROM locatedon1
12 WHERE locatedon1.country=c.code));
NAME
Spain
France
Sweden
SQL> Edited by: Dom Brooks on Jun 30, 2011 2:50 PM
Maybe you are looking for
-
Product Short description in SAR for MM-SUS scenario
Hello Experts, We are implementing MM-SUS scenario, where we are releasing the Schedule agreement for vendor. SAR is reaching to SUS, but the product short description is not appearing on the SAR screen on SUS. Could any one help us on this? Any solu
-
Text Content of Document is returned as null
Hi All, I am trying to use the JTidy parser to parse an input HTML string. But when I am trying to type the content of the Document, it is returning null. I am new to DOM parsing, so is there anything that I am doing wrong? Any pointer will be very h
-
Web service in Kava without Axis
Hi, I need to build a web service in Java. I tried Axis API (version 1.3) from Apache foundation. It works but I fear that web service managed by Axis are slow. So I maybe can write my web service without Axis. How can I do this ? Is it possible ? Wi
-
Activacion de Adobe Digital Editions 3.0,
Una vez descargado e instalado el programa, al abrir la Ayuda, no funciona "Autorizar equipo", ni "Información de autorización", por lo que no puedo abrir los e-books comprados. ¿Cómo se puede resolver este problema?
-
802.11r (Fast Transition) - multiple WLANs required for legacy clients?
Hello, I have a Cisco 5508 WLC with AIR-CAP3502E-E-K9 APs. I want to enable 802.11r (Fast Transition) and understand that some legacy clients may not support 802.11r and therefore if you select, for example, FT 802.1X as an authentication key manage