Analitical functions in recursive subquery factoring
Hi,
I have a problem with analitical functions in recursive subquery factoring.
My version:
>
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for 64-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
>
When I run following query it runs fine:
with a (num, total) as
(select
1 num
,1 total
from
dual
union all
select
num + 1 num
,total + num + 1 total
from
a
where
num < 10
select
from
a
NUM TOTAL
1 1
2 3
3 6
4 10
5 15
6 21
7 28
8 36
9 45
10 55
10 rows selected When I run the following query it generates an error:
with a (num, total) as
(select
1 num
,1 total
from
dual
union all
select
num + 1 num
,sum(num) over () total
from
a
where
num < 10
select
from
a
Error:
ORA-32486: unsupported operation in recursive branch of recursive WITH clause The manual states:
>
Oracle® Database
SQL Language Reference
11g Release 2 (11.2)
E17118-04
October 2010
The recursive member cannot contain any of the following elements:
- The DISTINCT keyword or a GROUP BY clause
- The model_clause
- An aggregate function. However, analytic functions are permitted in the select list.
- Subqueries that refer to query_name.
- Outer joins that refer to query_name as the right table.
>
According to this it should be posible to have an analitical function in here.
Also on this form I see samples of it used as such.
eg.:
Re: Seat Distribution-Can we do this in SQL?
Can anybody tell me if this is a problem with my version of oracle?
Or is there some other problem here?
Thanks,
Peter
Works ok in 11.2.0.3
SQL> select * from v$version;
BANNER
Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production
PL/SQL Release 11.2.0.3.0 - Production
CORE 11.2.0.3.0 Production
TNS for 64-bit Windows: Version 11.2.0.3.0 - Production
NLSRTL Version 11.2.0.3.0 - Production
SQL> with a (num, total) as
2 (select
3 1 num
4 ,1 total
5 from
6 dual
7 union all
8 select
9 num + 1 num
10 ,sum(num) over () total
11 from
12 a
13 where
14 num < 10
15 )
16 select
17 *
18 from
19 a
20 ;
NUM TOTAL
1 1
2 1
3 2
4 3
5 4
6 5
7 6
8 7
9 8
10 9
10 rows selected.
Similar Messages
-
Recursive WITH (Recursive Subquery Factoring) Never Returns
11.2.0.2 database on Windows, SQL Developer Version 3.2.20.09, build MAIN-09.87 (Database and SQL Developer are on the same machine. I have also tried connecting to a Linux 11.2 database and have the same results.)
I've been doing some simple testing with recursive WITH (Recursive Subquery Factoring) and when I run this following statement in SQL*Plus it returns instantly. However when running in SQL Developer it never returns, I've let it run for quite a long time (172 seconds) and gotten nothing, I finally kill the statement. Once I ran it and even killing the job didn't come back. I can get an explain plan but if I try to run it, run as script or autotrace it never returns. I have only one plan in the plan_table for this test, and it's only 4 lines long. No errors, no messages.
WITH get_plan (query_plan, id, planlevel) as
select ' '||operation||' '||options||' '||object_name query_plan, id, 1 planlevel
from plan_table
where id = 0
union all
select lpad(' ',2*planlevel)||p.operation||' '||p.options||' '||p.object_name query_plan, p.id, planlevel+1
from get_plan g, plan_table p
where g.id = p.parent_id
SELECT QUERY_PLAN FROM GET_PLAN ORDER BY PLANLEVEL;Hi Jeff, using either give the same results. The query is "running", as is the little graphic with the bouncing gray bar is moving back and forth saying either "Query Results" or "Scriptrunner Task" as appropriate.
OK this is odd. I run a count(*) on plan_table in SQL*Plus and get 4, in SQL Developer I get 487. Hun? That makes no sense I'm connect as the same user in each. Where are all these other entries coming from and why can't I see them in SQL Plus? Does SQL Developer have it's own PLAN_TABLE?
**EDIT --- Yes that seems to be the case. The PLAN_ID I see in SQL Plus doesn't even exist in the SQL Deveropler version of the table. OK that's good to know. I assume the plan_table for SQL Developer is local to it somehow? It's not in the database as best I can see.
Edited by: Ric Van Dyke on Feb 7, 2013 5:19 PM -
Recursive subquery factoring datatypes?
Hi all,
using 11.2.0.2.0
just mucking around with Recursive Subquery Factoring, trying to get my head around it.
I can do this fine:
SQL> with numlist (num) AS (SELECT 1 num
2 from dual
3 UNION ALL
4 SELECT numlist.num + 1
5 FROM numlist
6 where numlist.num < 10)
7 SELECT *
8 from numlist;
NUM
1
2
3
4
5
6
7
8
9
10
10 rows selected.but not with dates:
SQL> WITH datelist (dte) AS (SELECT to_date('01-01-2011','dd-mm-yyyy') Dte
2 FROM dual
3 UNION ALL
4 SELECT datelist.dte + 1
5 FROM datelist
6 WHERE datelist.dte < trunc(SYSDATE))
7 select *
8 from datelist;
SELECT datelist.dte + 1
ERROR at line 4:
ORA-01790: expression must have same datatype as corresponding expressionI'm not sure what I need to do.....
I'm sure it's a fairly straightforwardHemant K Chitale wrote:
I don't have an 11.2.0 environment to test this.
Try with a CAST at line 4 ? CAST X.DTE to a Date ?
Hemant K Chitaleahh, that's a little bit better.... it seems a little bit funky though:
15:38:58 SQL> WITH x (dte) AS (SELECT cast (to_date('01-01-2011','dd-mm-yyyy') as date) Dte
15:39:02 2 FROM dual
15:39:02 3 UNION ALL
15:39:02 4 SELECT cast(x.dte + 1 as date)
15:39:02 5 FROM x
15:39:02 6 WHERE x.dte < to_date('01-02-2011','dd-mm-yyyy'))
15:39:02 7 select *
15:39:02 8 from x;
DTE
01-JAN-11
31-DEC-10
30-DEC-10
29-DEC-10
28-DEC-10
27-DEC-10
26-DEC-10
25-DEC-10
24-DEC-10
23-DEC-10
22-DEC-10
21-DEC-10
20-DEC-10
19-DEC-10
18-DEC-10
17-DEC-10
16-DEC-10
15-DEC-10
14-DEC-10
13-DEC-10
12-DEC-10
11-DEC-10
10-DEC-10
09-DEC-10
08-DEC-10
07-DEC-10
06-DEC-10
05-DEC-10
04-DEC-10
03-DEC-10
02-DEC-10
01-DEC-10
30-NOV-10
29-NOV-10
28-NOV-10
27-NOV-10
26-NOV-10
25-NOV-10
24-NOV-10
23-NOV-10
22-NOV-10
21-NOV-10
20-NOV-10
...looks like it's going backwards.
if I cast it like the below, it only gives me one record...
15:39:03 SQL> WITH x (dte) AS (SELECT cast (to_date('01-01-2011','dd-mm-yyyy') as date) Dte
15:40:52 2 FROM dual
15:40:52 3 UNION ALL
15:40:52 4 SELECT cast(x.dte as date) + 1
15:40:52 5 FROM x
15:40:52 6 WHERE x.dte < to_date('01-02-2011','dd-mm-yyyy'))
15:40:52 7 select *
15:40:52 8 from x;
DTE
01-JAN-11
1 row selected.This is bizarre.... -
I have a table with origin and destination ids.
There can be a dynamic number of connections ( not expecting more than 5) and the relation is always one to one: A -->B-->C-->D
A or B or C or D can only apear in a relation, This mean A-->C cannot happen because A e already connected to B.
I want to create a querie that receives the last destination values and return a column with the origin values that are related with that value:
for example:
if my parameter value is D, my result will be a column with three rows : A,B,C
if my parameter value is C, my result will be a column with two rows : A,B
example:
create table test_list as (
select 32000 origin, 68200 destination from dual
union all
select 60000 origin, 168200 destination from dual
union all
select 8200 origin, 36600 destination from dual
union all
select 36600 origin, 8400 destination from dual
union all
select 8400 origin, 61800 destination from dual
)I tried conect by prior and connect by root but could not achieve it!
found also some articles about "Recursive Subquery Factoring" but that got even worst because I could not get it to work.
My database is "Oracle Database 11g Enterprise Edition Release 11.2.0.2.0 - 64bit Production"
SELECT origin from test_list where
origin in (select * FROM (
SELECT CONNECT_BY_ROOT destination
FROM test_list
CONNECT BY PRIOR origin = destination and destination =68200 )
)So in my list:
32000 connects to 68200
60000 connects to 168200
8200 connects to 36600
36600 connects to 8400
8400 connects to 61800
My expected results are:
If parameter "VALUE_TO_SEARCH" = 68200 I expect only: 32000
If parameter "VALUE_TO_SEARCH" = 168200 I expect only: 60000
If parameter "VALUE_TO_SEARCH" = 61800 I expect : 8400,36600,8200
If parameter "VALUE_TO_SEARCH" = 32000 I expect no results.
What should be the best method to use, for best performance and in case is with the CONNECT_BY_ROOT and " CONNECT BY PRIOR" what am I doing wrong there?
Best regards,
Ricardo TomásUse START WITH clause:
SQL> select * from test_list;
ORIGIN DESTINATION
32000 68200
60000 168200
8200 36600
36600 8400
8400 61800
SQL> select origin
2 from test_list
3 start with destination = &destination
4 connect by destination = prior origin
5 /
Enter value for destination: 68200
old 3: start with destination = &destination
new 3: start with destination = 68200
ORIGIN
32000
SQL> /
Enter value for destination: 168200
old 3: start with destination = &destination
new 3: start with destination = 168200
ORIGIN
60000
SQL> /
Enter value for destination: 61800
old 3: start with destination = &destination
new 3: start with destination = 61800
ORIGIN
8400
36600
8200
SQL> /
Enter value for destination: 32000
old 3: start with destination = &destination
new 3: start with destination = 32000
no rows selected
SQL> SY. -
Subquery Factoring and Materialized Hint
WITH t AS
(SELECT MAX (lDATE) tidate
FROM rate_Master
WHERE Code = 'G'
AND orno > 0
AND TYPE = 'L'
AND lDATE <= ':entereddate')
SELECT DECODE (:p1, 'B', RateB, 'S', RateS, Rate)
FROM rate_Master, t
WHERE Code = 'G'
AND orno > 0
AND TYPE = 'L'
AND NVL (lDATE, SYSDATE) = tidate;In the given example the sub query returns just one row because of the aggregate function max. Making this in to a With clause will be of any benefit ? Also i presume/understand that the subquery factoring would be really useful only when we try to make a sub query which returns more rows in a with clause. Is my intrepration right?
Secondly adding the /*+ Materialize */ hint to a With query is mandatory or the optimizer by itself will do it and make a temp table transformation. In my example i am forced to give the hint in the query. Please discuss and help
Thanks in advance.ramarun wrote:
WITH t AS
(SELECT MAX (lDATE) tidate
FROM rate_Master
WHERE Code = 'G'
AND orno > 0
AND TYPE = 'L'
AND lDATE <= ':entereddate')
SELECT DECODE (:p1, 'B', RateB, 'S', RateS, Rate)
FROM rate_Master, t
WHERE Code = 'G'
AND orno > 0
AND TYPE = 'L'
AND NVL (lDATE, SYSDATE) = tidate;In the given example the sub query returns just one row because of the aggregate function max. Making this in to a With clause will be of any benefit ? Also i presume/understand that the subquery factoring would be really useful only when we try to make a sub query which returns more rows in a with clause. Is my intrepration right?I am not aware of any performance Benefit due to use of With clause. IMO, It eases the job to write a Subquery multiple times in a query.
The solution you adopted has to hit the cache twice and hence do not look very performant. I will advise you to opt for Analytic functions (like the suggestion I provided in another thread). If the solution does not yeild correct results, then provide with a Script that we can replicate (Create table, Sample Insert statement and the expected output).
select decode(:p1, 'B', RateB, 'S', RateS, Rate)
from (
select RateB, RateS, Rate, NVL(ldate, sysdate) ldate, dense_rank() over (order by case when NVL(lDATE, SYSDATE) <= ':entereddate' then NVL(lDATE, SYSDATE) else to_date('01/01/1970', 'DD/MM/YYYY' end DESC) rn
from rate_Master
where Code = 'G'
and orno > 0
and type = 'L'
) a
where a.rn = 1;>
Secondly adding the /*+ Materialize */ hint to a With query is mandatory or the optimizer by itself will do it and make a temp table transformation. In my example i am forced to give the hint in the query. Please discuss and help
Usage of Hints is only for Debugging purposes and is not meant to be used in production code. It is when you have to ascertain the reason for CBO choosing a plan that you do not expect it to take, you use hints to force your plan and find the cost and analyze it. Hence, I do not support the idea of Hints for production code. -
How to use subquery factoring ("with" clause) in OWB?
Hi,
Is it possible to use subquery factoring (popularly known as "with" clause) in OWB 10gR2? I have a mapping with a splitter and union-all, which generates a query that has repeated scans of the same table. Subquery Factoring would be very useful here. I think this is a very common situation, so, I hope there's a way to achieve this. (If not in this version, this would be my wishlist item for the next version.)
Appreciate your help.
Regards,
RahulHi Rahul,
I'm afraid you have to put this on your wishlist. You may put the query with the "with"-clause into a view (or table function if you need parameters) if performance is too bad. But that is somehow against the idea (and benefits) of owb.
Another possibility is to use a temporary table and spilt the mappings into two parts: first fill the temp table, then the target table.
Regards,
Carsten. -
A function in a subquery is call too many times.
Dear all,
I'm struggling to understand why a function in a subquery is called too many times.
Let me explain with an example:
create or replace function all_emp (v_deptno in number)
return varchar2
as
v_all_emp varchar2(2000);
begin
dbms_output.put_line ('function called');
for i in (select * from emp where deptno = v_deptno) loop
v_all_emp := v_all_emp || i.ename || '; ';
end loop;
return v_all_emp;
end;
-- running just the subquery, calls the function all_emp only 4 times (once for each row in table dept)
select
d.deptno,
d.dname,
all_emp(d.deptno) f_all_emp
from dept d;
-- running the whole query, using regexp to split the value of f_all_emp into separate fields, causes that function all_emp is called 28 times, thus 6 times for each row!!
select tmp.*,
regexp_substr(f_all_emp,'[^;]*',1,1) emp1,
regexp_substr(f_all_emp,'[^;]*',1,3) emp2,
regexp_substr(f_all_emp,'[^;]*',1,5) emp3,
regexp_substr(f_all_emp,'[^;]*',1,7) emp4,
regexp_substr(f_all_emp,'[^;]*',1,9) emp5,
regexp_substr(f_all_emp,'[^;]*',1,11) emp6
from
(select
d.deptno,
d.dname,
all_emp(d.deptno) f_all_emp
from dept d) tmp
;I don't understand why Oracle is calling my function 28 times in this example, 4 times should be sufficient.
Is there a way to force that the subquery is materialized first?
Little background:
Above function / query is of course a simple example.
Actually I have pretty complex function, embedding in a subquery.
The subquery is already slow (2 min to run), but when I want to split the result of the funciton in multiple (approx 20) fields it's over an hour due to above described behaviour.Optimizer merges in-line view and query results in:
select d.deptno,
d.dname,
all_emp(d.deptno) f_all_emp
regexp_substr(all_emp(d.deptno),'[^;]*',1,1) emp1,
regexp_substr(all_emp(d.deptno),'[^;]*',1,3) emp2,
regexp_substr(all_emp(d.deptno),'[^;]*',1,5) emp3,
regexp_substr(all_emp(d.deptno),'[^;]*',1,7) emp4,
regexp_substr(all_emp(d.deptno),'[^;]*',1,9) emp5,
regexp_substr(all_emp(d.deptno),'[^;]*',1,11) emp6
from dept d
/That's why function is called 28 times. We can see it from explain plan:
SQL> explain plan for
2 select tmp.*,
3 regexp_substr(f_all_emp,'[^;]*',1,1) emp1,
4 regexp_substr(f_all_emp,'[^;]*',1,3) emp2,
5 regexp_substr(f_all_emp,'[^;]*',1,5) emp3,
6 regexp_substr(f_all_emp,'[^;]*',1,7) emp4,
7 regexp_substr(f_all_emp,'[^;]*',1,9) emp5,
8 regexp_substr(f_all_emp,'[^;]*',1,11) emp6
9 from (
10 select d.deptno,
11 d.dname,
12 all_emp(d.deptno) f_all_emp
13 from dept d
14 ) tmp
15 /
Explained.
SQL> @?\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
Plan hash value: 3383998547
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 4 | 52 | 3 (0)| 00:00:01 |
| 1 | TABLE ACCESS FULL| DEPT | 4 | 52 | 3 (0)| 00:00:01 |
8 rows selected.
SQL> If we use NO_MERGE hint:
SQL> select /*+ NO_MERGE(tmp) */
2 tmp.*,
3 regexp_substr(f_all_emp,'[^;]*',1,1) emp1,
4 regexp_substr(f_all_emp,'[^;]*',1,3) emp2,
5 regexp_substr(f_all_emp,'[^;]*',1,5) emp3,
6 regexp_substr(f_all_emp,'[^;]*',1,7) emp4,
7 regexp_substr(f_all_emp,'[^;]*',1,9) emp5,
8 regexp_substr(f_all_emp,'[^;]*',1,11) emp6
9 from (
10 select d.deptno,
11 d.dname,
12 all_emp(d.deptno) f_all_emp
13 from dept d
14 ) tmp
15 /
DEPTNO DNAME F_ALL_EMP EMP1 EMP2 EMP3 EMP4 EMP5 EMP6
10 ACCOUNTING CLARK; KIN CLARK KING MILLER
G; MILLER;
20 RESEARCH SMITH; JON SMITH JONES SCOTT ADAMS FORD
ES; SCOTT;
ADAMS; FO
RD;
30 SALES ALLEN; WAR ALLEN WARD MARTIN BLAKE TURNER JAMES
D; MARTIN;
DEPTNO DNAME F_ALL_EMP EMP1 EMP2 EMP3 EMP4 EMP5 EMP6
BLAKE; TU
RNER; JAME
S;
40 OPERATIONS
function called
function called
function called
function called
function called
function called
SQL> explain plan for
2 select /*+ NO_MERGE(tmp) */
3 tmp.*,
4 regexp_substr(f_all_emp,'[^;]*',1,1) emp1,
5 regexp_substr(f_all_emp,'[^;]*',1,3) emp2,
6 regexp_substr(f_all_emp,'[^;]*',1,5) emp3,
7 regexp_substr(f_all_emp,'[^;]*',1,7) emp4,
8 regexp_substr(f_all_emp,'[^;]*',1,9) emp5,
9 regexp_substr(f_all_emp,'[^;]*',1,11) emp6
10 from (
11 select d.deptno,
12 d.dname,
13 all_emp(d.deptno) f_all_emp
14 from dept d
15 ) tmp
16 /
Explained.
SQL> @?\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
Plan hash value: 2317111044
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 4 | 8096 | 3 (0)| 00:00:01 |
| 1 | VIEW | | 4 | 8096 | 3 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| DEPT | 4 | 52 | 3 (0)| 00:00:01 |
9 rows selected.
SQL> Not sure why function is executed 6 and not 4 times. What we actually want is to materialize in-line view:
SQL> with tmp as (
2 select /*+ materialize */
3 d.deptno,
4 d.dname,
5 all_emp(d.deptno) f_all_emp
6 from dept d
7 )
8 select tmp.*,
9 regexp_substr(f_all_emp,'[^;]*',1,1) emp1,
10 regexp_substr(f_all_emp,'[^;]*',1,3) emp2,
11 regexp_substr(f_all_emp,'[^;]*',1,5) emp3,
12 regexp_substr(f_all_emp,'[^;]*',1,7) emp4,
13 regexp_substr(f_all_emp,'[^;]*',1,9) emp5,
14 regexp_substr(f_all_emp,'[^;]*',1,11) emp6
15 from tmp
16 /
DEPTNO DNAME F_ALL_EMP EMP1 EMP2 EMP3 EMP4 EMP5 EMP6
10 ACCOUNTING CLARK; KIN CLARK KING MILLER
G; MILLER;
20 RESEARCH SMITH; JON SMITH JONES SCOTT ADAMS FORD
ES; SCOTT;
ADAMS; FO
RD;
30 SALES ALLEN; WAR ALLEN WARD MARTIN BLAKE TURNER JAMES
D; MARTIN;
DEPTNO DNAME F_ALL_EMP EMP1 EMP2 EMP3 EMP4 EMP5 EMP6
BLAKE; TU
RNER; JAME
S;
40 OPERATIONS
function called
function called
function called
function called
SQL> explain plan for
2 with tmp as (
3 select /*+ materialize */
4 d.deptno,
5 d.dname,
6 all_emp(d.deptno) f_all_emp
7 from dept d
8 )
9 select tmp.*,
10 regexp_substr(f_all_emp,'[^;]*',1,1) emp1,
11 regexp_substr(f_all_emp,'[^;]*',1,3) emp2,
12 regexp_substr(f_all_emp,'[^;]*',1,5) emp3,
13 regexp_substr(f_all_emp,'[^;]*',1,7) emp4,
14 regexp_substr(f_all_emp,'[^;]*',1,9) emp5,
15 regexp_substr(f_all_emp,'[^;]*',1,11) emp6
16 from tmp
17 /
Explained.
SQL> @?\rdbms\admin\utlxpls
PLAN_TABLE_OUTPUT
Plan hash value: 634594723
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
| 0 | SELECT STATEMENT | | 4 | 8096 | 5 (0)| 00:00:01 |
| 1 | TEMP TABLE TRANSFORMATION | | | | | |
| 2 | LOAD AS SELECT | | | | | |
| 3 | TABLE ACCESS FULL | DEPT | 4 | 52 | 3 (0)| 00:00:01 |
| 4 | VIEW | | 4 | 8096 | 2 (0)| 00:00:01 |
| 5 | TABLE ACCESS FULL | SYS_TEMP_0FD9D6603_20255AE | 4 | 52 | 2 (0)| 00:00:01 |
PLAN_TABLE_OUTPUT
12 rows selected.
SQL> However, hint MATERIALIZE is an undocumented hint.
SY. -
Aggregate Function in SQL subquery
Hello,
I am trying to use the following syntax and it is saying I can't use an aggregate function in a subquery. I can't use a GROUP BY in this case because if another field in the project table (such as status) is different, that project will show up twice.
So in this case I am using this syntax to show the most recent quote within the project.
SELECT PROJECT.*, QUOTE.QuoteDate, QUOTE.QuoteCode
FROM PROJECT LEFT JOIN QUOTE ON PROJECT.ProjectID = QUOTE.ProjectID
WHERE QUOTE.QuoteDate=(SELECT Max(Q.QuoteDate) FROM QUOTE Q WHERE Q.ProjectID = PROJECT.ProjectID);
My goal here is to show the most recent quote within each project (there can be multiple revisions of a quote within each project). I want to show other fields such as the status of the quote, but if the status is different between quotes, the GROUP BY on that
field will cause it to be listed more than once. All I want to show is the most recent quote for each project.
Let me know if this isn't clear.
Thanks.Try the below querySELECT P1.projectID,p1.QuoteDate, Q1.QuoteCode,p1.*
FROM PROJECT P1 inner join (SELECT Q.ProjectID,Max(Q.QuoteDate) QD FROM QUOTE Q group by Q.ProjectID) Q1 on Q1.ProjectID = P1.ProjectID and Q1.QD=P1.QuoteDate-Prashanth -
Bug in WITH clause (subquery factoring clause) in Oracle 11?
I'm using WITH to perform a set comparison in order to qualify a given query as correct or incorrect regarding an existing solution. However, the query does not give the expected result - an empty set - when comparing the solution to itself in Oracle 11 whereas it does in Oracle 10. A minimal example os posted below as script. There are also some observations about changes to the tables or the query that make Oracle 11 returning correct results but in my opinion these changes must not change the semantics of the queries.
Is this a bug or am I getting something wrong? The Oracle versions are mentioned in the script.
-- Bug in WITH clause (subquery factoring clause)
-- in Oracle Database 11g Enterprise Edition 11.2.0.1.0?
DROP TABLE B PURGE;
DROP TABLE K PURGE;
DROP TABLE S PURGE;
CREATE TABLE S (
m number NOT NULL,
x varchar2(30) NOT NULL
CREATE TABLE K (
k char(2) NOT NULL,
x varchar2(50) NOT NULL
CREATE TABLE B (
m number NOT NULL ,
k char(2) NOT NULL ,
n number
INSERT INTO S VALUES(1, 'h');
INSERT INTO S VALUES(2, 'l');
INSERT INTO S VALUES(3, 'm');
INSERT INTO K VALUES('k1', 'd');
INSERT INTO K VALUES('k2', 'i');
INSERT INTO K VALUES('k3', 'm');
INSERT INTO K VALUES('k4', 't');
INSERT INTO K VALUES('k5', 't');
INSERT INTO K VALUES('k6', 's');
INSERT INTO B VALUES(1, 'k1', 40);
INSERT INTO B VALUES(1, 'k2', 30);
INSERT INTO B VALUES(1, 'k4', 50);
INSERT INTO B VALUES(3, 'k1', 10);
INSERT INTO B VALUES(3, 'k2', 20);
INSERT INTO B VALUES(3, 'k1', 30);
INSERT INTO B VALUES(3, 'k6', 90);
COMMIT;
ALTER TABLE S ADD CONSTRAINT S_pk PRIMARY KEY (m);
ALTER TABLE K ADD CONSTRAINT K_pk PRIMARY KEY (k);
ALTER TABLE B ADD CONSTRAINT B_S_fk
FOREIGN KEY (m) REFERENCES S(m) ON DELETE CASCADE;
CREATE OR REPLACE VIEW v AS
SELECT S.m, B.n
FROM S JOIN B ON S.m=B.m JOIN K ON B.k=K.k
WHERE K.x='d'
ORDER BY B.n DESC;
-- Query 1: Result should be 0
WITH q AS
SELECT S.m, B.n
FROM S JOIN B ON S.m=B.m JOIN K ON B.k=K.k
WHERE K.x='d'
ORDER BY B.n DESC
SELECT COUNT(*)
FROM
SELECT * FROM q
MINUS
SELECT * FROM v
UNION ALL
SELECT * FROM v
MINUS
SELECT * FROM q
-- COUNT(*)
-- 6
-- 1 rows selected
-- Query 2: Result set should be empty (Query 1 without counting)
WITH q AS
SELECT S.m, B.n
FROM S JOIN B ON S.m=B.m JOIN K ON B.k=K.k
WHERE K.x='d'
ORDER BY B.n DESC
SELECT *
FROM
SELECT * FROM q
MINUS
SELECT * FROM v
UNION ALL
SELECT * FROM v
MINUS
SELECT * FROM q
-- M N
-- null 10
-- null 30
-- null 40
-- 1 40
-- 3 10
-- 3 30
-- 6 rows selected
-- Observations:
-- Incorrect results in Oracle Database 11g Enterprise Edition 11.2.0.1.0:
-- Query 1 returns 6, Query 2 returns six rows.
-- Correct in Oracle Database 10g Enterprise Edition 10.2.0.1.0.
-- Correct without the foreign key.
-- Correct if attribute x is renamed in S or K.
-- Correct if attribute x is left out in S.
-- Correct without the ORDER BY clause in the definition of q.
-- Only two results if the primary key on K is left out.
-- Correct without any change if not using WITH but subqueries (see below).
-- Fixed queries
-- Query 1b: Result should be 0
SELECT COUNT(*)
FROM
SELECT * FROM
SELECT S.m, B.n
FROM S JOIN B ON S.m=B.m JOIN K ON B.k=K.k
WHERE K.x='d'
ORDER BY B.n DESC
MINUS
SELECT * FROM v
UNION ALL
SELECT * FROM v
MINUS
SELECT * FROM
SELECT S.m, B.n
FROM S JOIN B ON S.m=B.m JOIN K ON B.k=K.k
WHERE K.x='d'
ORDER BY B.n DESC
-- COUNT(*)
-- 0
-- 1 rows selected
-- Query 2b: Result set shoud be empty (Query 1b without counting)
SELECT *
FROM
SELECT * FROM
SELECT S.m, B.n
FROM S JOIN B ON S.m=B.m JOIN K ON B.k=K.k
WHERE K.x='d'
ORDER BY B.n DESC
MINUS
SELECT * FROM v
UNION ALL
SELECT * FROM v
MINUS
SELECT * FROM
SELECT S.m, B.n
FROM S JOIN B ON S.m=B.m JOIN K ON B.k=K.k
WHERE K.x='d'
ORDER BY B.n DESC
-- M N
-- 0 rows selectedYou're all gonna love this one.....
The WITH clause works. But not easily.
Go ahead, build the query, (as noted in a recent thread, I, too, always use views), set the grants and make sure DISCOVERER and EULOWNER have SELECT privs.
1. Log into Disco Admin as EULOWNER. Trust me.
2. Add the view as a folder to the business area.
3. Log into Disco Desktop as EULOWNER. Don't laugh. It gets better.
4. Build the workbook and the worksheet (or just the worksheet if apropos)
5. Set the appropriate "sharing" roles and such
6. Save the workbook to the database.
7. Save the workbook to your computer.
8. Log out of Desktop.
9. Log back into Desktop as whatever, whoever you usually are to work.
10. elect "open existing workbook"
11. Select icon for "open from my computer". See? I told you it would get better!
12. Open the save .dis file from your computer.
13. Save it to the database.
14. Open a web browser and from there, you're on your own.
Fortran in VMS. Much easier and faster. I'm convinced the proliferation of the web is a detriment to the world at large...On the other hand, I'm also waiting for the Dodgers to return to Brooklyn. -
Subquery factoring and DB Link
Hello,
2 node RAC
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
PL/SQL Release 10.2.0.5.0 - Production
CORE 10.2.0.5.0 Production
TNS for Linux: Version 10.2.0.5.0 - Production
NLSRTL Version 10.2.0.5.0 - ProductionI have a query of the form..
WITH temp as
(select col1, col2, col3 from LOCAL_TABLE)
SELECT /*+ driving_site (remote1) */
remote1.col1,
remote1.col1,
remote1.col1,
remote1.col1,
remote1.col1,
remote1.col1,
remote2.col1,
remote2.col1,
remote2.col1,
remote2.col1,
remote2.col1,
null,
null
from remote_view1@dblink remote1, -- Remote View over 2 dbs
remote_view2@dblink remote2 -- Remote View over 2 dbs
where remote1.col1 in (select col1 from temp);This query used to work, but recently there has been a change in remote_view1 after which the query takes a long time to execute.
The good performing query takes 2 secs, while the bad performing one takes about 8 minutes.
However, if I remove the subquery factoring and include the query as a sub-query it works well.
SELECT /*+ driving_site (remote1) */
remote1.col1,
remote1.col1,
remote1.col1,
remote1.col1,
remote1.col1,
remote1.col1,
remote2.col1,
remote2.col1,
remote2.col1,
remote2.col1,
remote2.col1,
null,
null
from remote_view1@dblink remote1, -- Remote View over 2 dbs
remote_view2@dblink remote2 -- Remote View over 2 dbs
where remote1.col1 in (select col1, col2, col3 from LOCAL_TABLE);I tried to check the data from v$sql. I observed that;
v$sql.remote = 'Y' - good performance
v$sql.remote = 'N' - bad performance
Has anyone faced this situation ?
Rgds,
GokulAm I right in assuming that queries executed entirely on remote db don't have plans stored in v$sql_planRight.
SQL> select /*+ domtest */ 1 from dual@domtest;
1
1
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID 9d51rf84zvt0s, child number 0
select /*+ domtest */ 1 from dual@domtest
NOTE: cannot fetch plan for SQL_ID: 9d51rf84zvt0s, CHILD_NUMBER: 0
Please verify value of SQL_ID and CHILD_NUMBER;
It could also be that the plan is no longer in cursor cache (check v$sql_plan)
8 rows selected.
SQL> select sql_id, remote, sql_text from v$sql where sql_id = '9d51rf84zvt0s';
SQL_ID R SQL_TEXT
9d51rf84zvt0s Y select /*+ domtest */ 1 from dual@domtest
SQL> select * from v$sql_plan where sql_id = '9d51rf84zvt0s';
no rows selected
SQL> select /*+ domtest */ 1 from dual@domtest t, dual;
1
1
Elapsed: 00:00:00.00
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID d0m08znks4yak, child number 0
select /*+ domtest */ 1 from dual@domtest t, dual
Plan hash value: 3754369022
| Id | Operation | Name | Rows | Cost (%CPU)| Time | Inst |IN-OUT|
| 0 | SELECT STATEMENT | | | 4 (100)| | | |
| 1 | MERGE JOIN CARTESIAN| | 1 | 4 (0)| 00:00:01 | | |
| 2 | REMOTE | DUAL | 1 | 2 (0)| 00:00:01 | DOMTE~ | R->S |
| 3 | BUFFER SORT | | 1 | 2 (0)| 00:00:01 | | |
| 4 | FAST DUAL | | 1 | 2 (0)| 00:00:01 | | |
Remote SQL Information (identified by operation id):
2 - SELECT 0 FROM "DUAL" "T" (accessing 'DOMTEST' )
22 rows selected.
Elapsed: 00:00:00.04
SQL> select sql_id, remote, sql_text from v$sql where sql_id = 'd0m08znks4yak';
SQL_ID R SQL_TEXT
d0m08znks4yak N select /*+ domtest */ 1 from dual@domtest t, dua
SQL> select /*+ driving_site(t) */ 1 from dual@domtest t, dual;
1
1
Elapsed: 00:00:00.00
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
SQL_ID 741u736nrk6dx, child number 0
select /*+ driving_site(t) */ 1 from dual@domtest t, dual
NOTE: cannot fetch plan for SQL_ID: 741u736nrk6dx, CHILD_NUMBER: 0
Please verify value of SQL_ID and CHILD_NUMBER;
It could also be that the plan is no longer in cursor cache (check v$sql_plan)
8 rows selected.
Elapsed: 00:00:00.01
SQL> select sql_id, remote, sql_text from v$sql where sql_id = '741u736nrk6dx';
SQL_ID R SQL_TEXT
741u736nrk6dx Y select /*+ driving_site(t) */ 1 from dual@domtest
t, dual
Elapsed: 00:00:00.00
SQL>
SQL> select * from v$sql_plan where sql_id = '741u736nrk6dx';
no rows selected
Elapsed: 00:00:00.01
SQL> Edited by: Dom Brooks on Aug 21, 2012 1:05 PM -
Analitic functions (problem with SELECT)
Hi!
I've got a problem with analitic functions (I'm newbie in this topic).
I have a table gpw_notowania which have colums: not_open, not_minimum, not_maximum, not_close, not_volume, not_sp_id and not_date.
I need to receive from database the information: what is the open, minimum, maximum, close and sum of volume in every week? I have tried the code below but it tells me: ORA-01791 (marking not_date in ORDER clause).
Help me, please.
SELECT distinct
FIRST_VALUE(not_open) OVER (partition by to_char(not_date,'WW') ORDER BY not_date) as open,
MIN(not_minimum) OVER (partition by to_char(not_date,'WW') ORDER BY not_date) as minimum,
MAX(not_maximum) OVER (partition by to_char(not_date,'WW') ORDER BY not_date) as maximum,
FIRST_VALUE(not_close) OVER (partition by to_char(not_date,'WW') ORDER BY not_date DESC) as close,
sum(not_volume) OVER (partition by to_char(not_date,'WW')) as volume
FROM gpw_notowania
WHERE not_sp_id = 80
ORDER BY not_date;This is an interesting question.
create table SortWithDistinct(Val1,Val2,sortKey,SubSortKey) as
select 1,3,10,1 from dual union all
select 1,3,10,1 from dual union all
select 1,3,10,1 from dual union all
select 2,4,30,2 from dual union all
select 2,4,30,2 from dual union all
select 3,5,20,1 from dual union all
select 3,5,20,1 from dual union all
select 4,6,10,3 from dual union all
select 5,5,10,2 from dual union all
select 5,5,10,2 from dual union all
select 9,9,10,4 from dual union all
select 6,4,20,2 from dual union all
select 6,4,20,2 from dual union all
select 7,3,30,1 from dual union all
select 7,3,30,1 from dual;
select distinct Val1,Val2
from SortWithDistinct
order by sortKey,SubSortKey;
ORA-01791: not a SELECTed expressionIt is one way that we use "group by".
for instance
select Val1,Val2
from SortWithDistinct
group by Val1,Val2
order by max(sortKey),max(SubSortKey);
Val1 Val2
1 3
5 5
4 6
9 9
3 5
6 4
7 3
2 4It is one way that we use "Inline View".
for instance
select Val1,Val2
from (select distinct Val1,Val2,sortKey,SubSortKey
from SortWithDistinct)
order by sortKey,SubSortKey;
Furthermore, we may use below alternative solution which uses "dense_Rank".
select Val1,Val2
from (select distinct Val1,Val2,
dense_Rank() over(order by sortKey,SubSortKey) as willSortKey
from SortWithDistinct)
order by willSortKey;Because "distinct" works after OLAP.
for instance
SQL> select distinct ColA,ColB,Row_Number() over(order by 1) as Rank
2 from (select 1 as ColA,1 as ColB from dual
3 union all select 1,1 from dual
4 union all select 1,1 from dual
5 union all select 1,1 from dual
6 union all select 2,2 from dual
7 union all select 2,2 from dual
8 union all select 2,2 from dual)
9 order by 1,2,3;
ColA ColB Rank
1 1 1
1 1 2
1 1 3
1 1 4
2 2 5
2 2 6
2 2 7my site :-)
http://www.geocities.jp/oraclesqlpuzzle/1-6.html -
Subquery Factoring -Performance Issue
Hi experts,
Oracle 10G
select
a.colums,
b.columns
from
( select
Colums
from
F ,
(select
columns
from
bigtable
where
<condition with recdate and modified date with timezone convertions Given as in end of this qury)
) a,
( select
Colums
from
tables,
(select
columns
from
bigtable
where
<condition with recdate and modified date with timezone convertions Given as in end of this qury)
) b
(TO_DATE(TO_CHAR(FROM_TZ(CAST(CF.RECDT as timestamp),'GMT') at time zone 'America/Chicago','YYYY-MM-DD
HH24:MI:SS'),'YYYY-MM-DD HH24:MI:SS')
BETWEEN TO_DATE('01-JAN-2009 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('08-JAN-2009 00:00:00', 'DD-MON-YYYY
HH24:MI:SS')) OR
(TO_DATE(TO_CHAR(FROM_TZ(CAST(CF.MODIFID_DT as timestamp),'GMT') at time zone 'America/Chicago','YYYY-MM-DD
HH24:MI:SS'),'YYYY-MM-DD HH24:MI:SS')
BETWEEN TO_DATE('01-JAN-2009 00:00:00','DD-MON-YYYY HH24:MI:SS') AND TO_DATE('08-JAN-2009 00:00:00', 'DD-MON-YYYY
HH24:MI:SS'))
Recdt - indexed
Modifieddt - not iddexed
bigtable used many times in select to avoid Subquery factoring used (with select) but it increased cost as per explain plan in sqldevleoper please suggest me to increase performance
Lots of thanks,
Kalinganow the above query use as
with subfact as
( select
select
columns
from
bigtable
where
<condition with recdate and modified date
select
a.colums,
b.columns
from
( select
Colums
from
F ,
subfact
where condition
) a,
( select
Colums
from
tables,
subfact
where condition
) b
it is cost increased in nested loop in explain plan why? is thre any other detail required. -
WITH Subquery Factoring OR "Scalar SubqueriesRun Another Query per row
Hi Experts
Please suggest
which one query is better
Involved table p is of size 2GB and c1/c2 of size 800M.
And we have to run a report on p which will do FTS (no where clause on p)
So FTS on 2 GB table and then running Another Query per row .. so results job very slow
1) Select p.id,
(select sum(q1) from c1 where c1.id = p.id) c1_sum1,
(select sum(q2) from c2 where c2.id = p.id) c2_sum2
from p
2)
WITH Subquery Factoring
with c1_vw as
(select id, sum(q1) c1_sum1
from c1
group by id),
c2_vw as
(select id, sum(q2) c2_sum2
from c2
group by id),
c1_c2 as
(select c1.id, c1.c1_sum1, c2.c2_sum2
from c1_vw c1, c2_vw c2
where c1.id = c2.id )
select p.id, c1_sum1, c2_sum2
from p, c1_c2
where p.id = c1_c2.id
/ 10.2..0.4
AIX 5.3
Thanks In Advance
ivwivw wrote:
which one query is betterThe better query IMHO is the one that returns the the correct results in the shortest amount of time using the least system resources (the last two items usually happen at the same time). Maintainability is an issue too. Which one do you like best?
Its hard to say which query will run best without running both, getting execution plans, and run-time statistics. At a pure guess I would think all things being equal they would have similar performance but do not really know. -
With clause of select (subquery factoring)
I've got a script that looks like this:
with X as (select * from atable)
select x1.*, x2.*
from X x1,
X x2
This works perfectly well in SQL*Plus, in PL/SQL, etc. Yet when I try to add it as "New Folder from Database" to an existing Business area in Discoverer, I get the infamous "ORA-03001 Unimplemented Feature".
What am I doing wrong?
Oracle 9i, Disco 9.0.4Hi,
You will have to define a database view containing your query and load the view into your database. I don't think you can use subquery factoring in a custom folder.
Rod West -
When does OBIEE forcibly use Subquery Factoring ?
In a 10.2 "datawarehouse" schema I see OBIEE queries of the form :
WITH SAWITH0 AS (select distinct T12345.COLUMN_1 as c1 from DIMENSION_TABLE T12345
where ( T12345.COLUMN_1 like 'HEMANT%')
) select distinct SAWITH0.c1 as c1 from SAWITH0I cannot understand why OBIEE wouldn't run a simpler
select distinct T12345.COLUMN_1 as c1 from DIMENSION_TABLE T12345
where ( T12345.COLUMN_1 like 'HEMANT%')What OBIEE setup would cause even simple queries to be generated as using Subquery Factoring ?
Hemant K Chitale
http://hemantoracledba.blogspot.comHi Hemant,
use of WITH can be disabled in the OBIEE RPD Connection pool. Its enabled by default to allow the performance benefit you would see when using aggregated result sets. I personally think the OBIEE server is simply not advanced enough to determine when it doesn't need to use it (ie when selecting distinct dimension member values in dashboard prompts).
Just my 2c. Hopefully some of the experianced users on here can expand a little more for you. Id be interested to know as well.
Maybe you are looking for
-
Import Statement Different ways to refer ???
Dear Friends, Can any one help me the difference between the usage of import statement.... 1. using import statement 2. using the class directly that is, for example ; 1. import java.util.Date; Date dt = new Date(); 2. java.util.Date dt = new java.ut
-
Time_out dump error in RSTXSCRP while Importing SAP Script
Hi Experts, I am using RSTXSCRP program for Download and Upload the SAP Form. I am downloading script 'ZF110_HDFC_CHCK' is successfully. after that before uploading i open the notepad i replace 'ZF110_HDFC_CHCK' to 'ZF110_HDFC_DM'. then in selecti
-
How to add two objects on scene and how to rotate them?
I am beginer on 3d. I am trying do write applet where are 3x3x3 rubic. My plans are to have 27 litle cubes. There are 6 flats (9 cubes in a flat) so i have six objects groups. My problem at this moment is that i cant find out how to make two objets.
-
Item too large for volume's format fat32
Lion os . External HD Fat32. I try copy files and receive msg: item too large for volume's format
-
Apple charged me £20.99 for in-app purchase for an app I just bought an hour ago while I did not bought any in-app purchase. How could I make claim and refund this money?