With clause - 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.4
You'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.
Similar Messages
-
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. -
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 -
WITH clause unexpectedly causes ORA-00942 in Reports Builder
I'm posting this in the hope that:
a) My workaround might help someone if they ever run into the same problem, and/or,
b) Someone might have a better workaround.
The problem is that I get unexpected ORA-00942 (table or view does not exist) errors when I try to set the SQL Query Statement property of a Query object in Reports Builder to certain SELECT statements that contain a WITH clause (aka subquery factoring clause).
For example, the following SELECT statement executes as expected in SQL*Plus...
SQL> WITH
2 SUB_QUERY AS
3 (
4 SELECT
5 1 AS X
6 FROM
7 DUAL
8 )
9 SELECT
10 INLINE_VIEW.X
11 FROM
12 (
13 SELECT
14 NESTED_INLINE_VIEW.X
15 FROM
16 (
17 SELECT
18 SUB_QUERY.X
19 FROM
20 SUB_QUERY
21 ) NESTED_INLINE_VIEW
22 ) INLINE_VIEW;
X
1...but when I try to use it as the SQL Query Statement for a Query object in Reports Builder, I get the following error:
ORA-00942: table or view does not exist
==>SUB_QUERY
My Reports Builder version is 10.1.2.0.2 version and my database version is 10.2.0.3.0.
The "real" query I have been trying to use is much more complex than this -- this is just the simplest statement I have been able to come up with that causes the problem. In fact, I have some queries that have a similar structure (a WITH clause subquery referenced inside a nested inline view, along with some other things), but strangely do not cause the problem.
I spent some time researching the problem on Google and Metalink but did not come up with any satisfactory answers. The problem sounds similar to bug 3896963, but bug 3896963 involved UNION ALL, and is supposedly fixed in my version(s).
I tried various ways of restructuring my "real" query, but with no success -- it's going to be hard to get rid of the WITH clauses. As a "wild guess", I tried various hints (MATERIALIZE, NO_PUSH_PRED, NO_MERGE), again with no success.
I ended up working around the problem by creating a database package with a function that returns a REF CURSOR based on the query, and then used that in a REF CURSOR query in Reports Builder. It might not be a very elegant workaround, but it works. I just wish I had "given up" and tried it sooner -- I might have saved myself some grief.Well, for what it's worth, I didn't end up using a REF CURSOR query after all because...
If I ran a REP file based on a REF CURSOR query against a different database, or if I ran the REP file after the database package had been dropped and re-created, it failed with the following error:
REP-8: Run time error in the PL/SQL development environment (DE).
PDE-PSD001 Could not resolve reference to <Unknown Program Unit> while loading <Unknown> <Unknown>.
REP-0008: Unexpected memory error while initializing preferences.
It seems that Reports "binds" the REP file to the timestamp of the database package that defines the REF CURSOR type in order to validate the package at run time. If the timestamp is different, running the REP file will fail with this error. This is apparently bug 1275333 and is described in Metalink Note 272936.1.
The bug reference and Metalink Note offerred the following workarounds:
1. Export the database schema that contains the package from one database and import it into the other.
In some versions, import and export preserve the timestamp, so this would avoid the problem. I didn't try this because it would not be a practical workaround in my situation (upgrade vs. new install).
2. Recompile the package and manually set the timestamp using the seemingly undocumented ALTER PACKAGE...COMPILE BODY REUSE SETTINGS TIMESTAMP... syntax.
I didn't try this because I didn't like the idea of having to: a) rely on an undocumented feature, and, b) manually keep track and maintain the timestamps of all the affected packages across several databases (e.g., development, test, and production).
3. Put the package into a Reports library or into the report itself.
This didn't work for me because Reports does not understand WITH clauses in PL/SQL. For example, with the example query in my previous post, I get an error like this:
Error 103 at line {line defining name of factored subquery}, column {first column in line defining name of factored subquery}
Encountered the symbol "SUB_QUERY" when expecting one of the following:
<a SQL statement>
4. Use an RDF file instead of a REP file.
I didn't use this workaround because I wanted to protect the design of the report by using a REP file instead of an RDF file.
So instead, I:
1. Created a database package containing a pipelined function that returned the results of the WITH clause query that Reports did not "understand".
2. Used an SQL query in my report of the form
SELECT * FROM TABLE(MY_PACKAGE.MY_PIPELINED_FUNCTION(arg1, arg2, ...))
I can drop and re-create the package and run the REP file against another database both without leading to the REP-8 error. -
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.... -
Hi can any say whether we can use with caluse in cursors.
any select query having dynamic views in from clause can be used as with, and can be used in cursor tooo
example of with
http://nimishgarg.blogspot.com/2010/05/oracle-sql-with-clause-subquery.html -
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. -
OBIEE 11g "WITH SAWITH0 AS" subquery factoring clause in the generated sql
I've observed that the OBIEE 11g generates in the query log physical query using the WITH (sub-query factoring) clause to make the generated sql elegantly readable. This is great! Thanks for the developers. However I have some questions about this.
__Background__
Oracle Database' default behaviour is that if you have only one sub-query in the WITH section, it executes it as an in-line view and does not materialize it before the main sql is executed. If you have more than one, by default the database engine materializes all of them in the order of the definition. In some cases this can completely blow up the SGA and make the query never ending. To divert this behaviour you can apply two hints that work both in inline views and in sub-queries as well: /*+ MATERIALIZE */ and /*+ INLINE*/, however Analytics 11g does not seem to have hint capabilities at the logical table level, only at physical table level.
If we go with the current defaults, developers not aware of this feature can bump into serious performance issues for the sake of some syntax candy at the generated sql level, I'm afraid.
__Questions__
* Is it possible to turn the Analytics server not to use WITH but use inline views instead?
* Is there any way to sneak in some hints that would put the /*+ INLINE */ hint to the appropriate place in the generated sub-queries if needed
* Does the Oracle Database have any initialization parameter that can influence this sub-query factoring behavior and divert from the default?The WITH statement is not added to make the query more elegant, it's added for performance reasons. If your queries take long to run then you may have a design issue. In a typical DWH DB SGA needs to be seriously increased since the queries ran are much larger and complex than on an OLTP DB. In any case you can disable the WITH statement in the Admin Tool by double clicking on your database object on the physical layer and going to the Features tab. The feature is called WITH_CLAUSE_SUPPORTED.
-
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 -
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. -
My DB version is 10.2.0
One of my query takes long time for execution and here is the Old Query,
SELECT HD.DATUM DATUM, HA2.GELDEINGAENGE_INSG-NVL(HA3.VERWERTUNGSERLOESE,0)
GELDEINGANG, HA3.VERWERTUNGSERLOESE
FROM
( SELECT DISTINCT(TO_CHAR(ERFASSDATUM,'YYYY/MM')) DATUM
FROM TRANS_HIST H1 ,
(SELECT BUCHUNGSGRUPPE, LFDNR, SICHERHEITBEZUG
FROM BUCHUNGSSCHL
WHERE STORNOMM=0) B1
WHERE H1.ERFASSDATUM >=TO_DATE('01.10'||TO_CHAR(ADD_MONTHS(SYSDATE,-9),'YYYY')||' 00.00.00','DD.MM.YYYY HH24:MI:SS')
AND H1.BUCHUNGSGRUPPE = B1.BUCHUNGSGRUPPE AND H1.LFDNR = B1.LFDNR
AND (H1.BUCHUNGSGRUPPE = '8888' OR ( H1.BUCHUNGSGRUPPE > 5999 AND H1.BUCHUNGSGRUPPE < 7100 AND B1.SICHERHEITBEZUG = 1)) ) HD,
(SELECT TO_CHAR(ERFASSDATUM,'YYYY/MM') DATUM, SUM(BETRAG) GELDEINGAENGE_INSG
FROM TRANS_HIST H2,
(SELECT F.GLAEUBIGERNR,F.FORDNR,F.FORDERGNR,A.MAHN_NUM
FROM FRD_ACCT F,
(SELECT * FROM ANS_PRCH WHERE RANGMM=1) A
WHERE F.GLAEUBIGERNR=A.GLAEUBIGERNR (+) AND F.FORDNR=A.FORDNR(+)
AND F.FORDERGNR=A.FORDERGNR(+) AND NVL(F.INDIVIDUALFLAG,0)=0 ) F1
WHERE ( (F1.GLAEUBIGERNR= H2.GLAEUBIGERNR AND F1.FORDNR=H2.FORDNR AND F1.FORDERGNR=H2.FORDERGNR) OR
F1.MAHN_NUM = H2.MAHN_NUM) AND H2.BUCHUNGSGRUPPE = '8888' AND
H2.ERFASSDATUM >= TO_DATE('01.10'||TO_CHAR(ADD_MONTHS(SYSDATE,-9),'YYYY')||' 00.00.00','DD.MM.YYYY HH24:MI:SS')
GROUP BY TO_CHAR(ERFASSDATUM,'YYYY/MM') ) HA2,
(SELECT TO_CHAR(ERFASSDATUM,'YYYY/MM') DATUM, SUM(BETRAG) VERWERTUNGSERLOESE
FROM TRANS_HIST H3, (SELECT BUCHUNGSGRUPPE, LFDNR,
SICHERHEITBEZUG, NACHMIETVERTRAGE
FROM BUCHUNGSSCHL
WHERE STORNOMM=0) B3,
(SELECT F.GLAEUBIGERNR,F.FORDNR,F.FORDERGNR,A.MAHN_NUM
FROM FRD_ACCT F,
(SELECT * FROM ANS_PRCH WHERE RANGMM=1) A
WHERE F.GLAEUBIGERNR= A.GLAEUBIGERNR (+) AND F.FORDNR=A.FORDNR(+)
AND F.FORDERGNR=A.FORDERGNR(+) AND NVL(F.INDIVIDUALFLAG,0)=0 ) F2
WHERE ( (F2.GLAEUBIGERNR=H3.GLAEUBIGERNR AND F2.FORDNR=H3.FORDNR AND F2.FORDERGNR=H3.FORDERGNR)
OR F2.MAHN_NUM = H3.MAHN_NUM)
AND H3.ERFASSDATUM >=TO_DATE('01.10'||TO_CHAR(ADD_MONTHS(SYSDATE,-9),'YYYY')||' 00.00.00','DD.MM.YYYY HH24:MI:SS')
AND H3.BUCHUNGSGRUPPE = B3.BUCHUNGSGRUPPE AND
H3.LFDNR = B3.LFDNR AND H3.BUCHUNGSGRUPPE > 5999
AND H3.BUCHUNGSGRUPPE < 7100 AND (B3.SICHERHEITBEZUG = 1 OR B3.NACHMIETVERTRAGE =1)
GROUP BY TO_CHAR(ERFASSDATUM,'YYYY/MM') ) HA3
WHERE HD.DATUM=HA2.DATUM (+)
AND HD.DATUM=HA3.DATUM (+)
ORDER BY DATUM ASC
call count cpu elapsed disk query current rows
Parse 1 0.22 0.22 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 469.61 1448.30 2874498 3017355 1 9
total 3 469.83 1448.53 2874498 3017355 1 9
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 62 (recursive depth: 1)
Rows Row Source Operation
9 SORT ORDER BY (cr=3017355 pr=2874498 pw=0 time=1448309418 us)
9 HASH JOIN RIGHT OUTER (cr=3017355 pr=2874498 pw=0 time=1448309191 us)
9 VIEW (cr=1228085 pr=1175604 pw=0 time=906871801 us)
9 HASH GROUP BY (cr=1228085 pr=1175604 pw=0 time=906871785 us)
1559 CONCATENATION (cr=1228085 pr=1175604 pw=0 time=564453620 us)
233 HASH JOIN (cr=614043 pr=589377 pw=0 time=562088377 us)
94 TABLE ACCESS FULL BUCHUNGSSCHL (cr=29 pr=0 pw=0 time=505 us)
254136 HASH JOIN (cr=614014 pr=589377 pw=0 time=509476999 us)
497464 TABLE ACCESS FULL TRANS_HIST (cr=586339 pr=562603 pw=0 time=65783878 us)
737515 HASH JOIN RIGHT OUTER (cr=27675 pr=26774 pw=0 time=18577731 us)
372656 TABLE ACCESS FULL ANS_PRCH (cr=6346 pr=5910 pw=0 time=408778 us)
737515 TABLE ACCESS FULL FRD_ACCT (cr=21329 pr=20864 pw=0 time=2254657 us)
1326 HASH JOIN (cr=614042 pr=586227 pw=0 time=520726941 us)
94 TABLE ACCESS FULL BUCHUNGSSCHL (cr=29 pr=0 pw=0 time=641 us)
221360 FILTER (cr=614013 pr=586227 pw=0 time=372791872 us)
221360 HASH JOIN OUTER (cr=614013 pr=586227 pw=0 time=372570499 us)
221360 HASH JOIN (cr=607668 pr=580286 pw=0 time=368077766 us)
243053 TABLE ACCESS FULL TRANS_HIST (cr=586339 pr=563978 pw=0 time=1425434011 us)
737515 TABLE ACCESS FULL FRD_ACCT (cr=21329 pr=16308 pw=0 time=8859226 us)
372656 TABLE ACCESS FULL ANS_PRCH (cr=6345 pr=5941 pw=0 time=1872464 us)
9 HASH JOIN OUTER (cr=1789270 pr=1698894 pw=0 time=541436637 us)
9 VIEW (cr=586667 pr=562439 pw=0 time=213337882 us)
9 HASH UNIQUE (cr=586667 pr=562439 pw=0 time=213337873 us)
748717 HASH JOIN (cr=586667 pr=562439 pw=0 time=104432018 us)
830 TABLE ACCESS FULL BUCHUNGSSCHL (cr=29 pr=0 pw=0 time=1042 us)
1241936 TABLE ACCESS FULL TRANS_HIST (cr=586638 pr=562439 pw=0 time=339666777 us)
9 VIEW (cr=1202603 pr=1136455 pw=0 time=328097826 us)
9 HASH GROUP BY (cr=1202603 pr=1136455 pw=0 time=328097809 us)
695373 CONCATENATION (cr=1202603 pr=1136455 pw=0 time=324453471 us)
0 HASH JOIN (cr=587003 pr=557994 pw=0 time=167168982 us)
744472 TABLE ACCESS FULL TRANS_HIST (cr=587003 pr=557994 pw=0 time=30622271 us)
0 HASH JOIN RIGHT OUTER (cr=0 pr=0 pw=0 time=0 us)
0 TABLE ACCESS FULL ANS_PRCH (cr=0 pr=0 pw=0 time=0 us)
0 TABLE ACCESS FULL FRD_ACCT (cr=0 pr=0 pw=0 time=0 us)
695373 FILTER (cr=615600 pr=578461 pw=0 time=157284464 us)
695373 HASH JOIN OUTER (cr=615600 pr=578461 pw=0 time=156589072 us)
695373 HASH JOIN (cr=609255 pr=572518 pw=0 time=150571393 us)
744472 TABLE ACCESS FULL TRANS_HIST (cr=587926 pr=556115 pw=0 time=31820718 us)
737515 TABLE ACCESS FULL FRD_ACCT (cr=21329 pr=16403 pw=0 time=3696334 us)
372656 TABLE ACCESS FULL ANS_PRCH (cr=6345 pr=5943 pw=0 time=391928 us)I tried fine tuning the query using "With Clause" but landed up with oracle error, which prevents me from using with clause inside a paranthesis.
SELECT HD.DATUM DATUM, HA2.GELDEINGAENGE_INSG-NVL(HA3.VERWERTUNGSERLOESE,0)
GELDEINGANG, HA3.VERWERTUNGSERLOESE
FROM
( WITH HIST_VIEW AS (SELECT GLAEUBIGERNR,FORDNR,FORDERGNR,MAHN_NUM,BUCHUNGSGRUPPE,LFDNR,STORNOMM,ERFASSDATUM,BETRAG
FROM TRANS_HIST H
WHERE ERFASSDATUM >=TO_DATE('01.10'||TO_CHAR(ADD_MONTHS(SYSDATE,-9),'YYYY')||' 00.00.00','DD.MM.YYYY HH24:MI:SS')
AND (H.BUCHUNGSGRUPPE = '8888' OR ( H.BUCHUNGSGRUPPE > 5999 AND H.BUCHUNGSGRUPPE < 7100))),
FORD_VIEW AS (SELECT F.GLAEUBIGERNR,F.FORDNR,F.FORDERGNR,A.MAHN_NUM
FROM FRD_ACCT F,ANS_PRCH A
WHERE F.GLAEUBIGERNR=A.GLAEUBIGERNR(+) AND F.FORDNR=A.FORDNR(+)
AND F.FORDERGNR=A.FORDERGNR(+) AND NVL(F.INDIVIDUALFLAG,0)=0 AND A.RANGMM=1)
(SELECT DISTINCT(TO_CHAR(ERFASSDATUM,'YYYY/MM')) DATUM
FROM HIST_VIEW H1 ,BUCHUNGSSCHL B1
WHERE B1.STORNOMM=0 AND H1.BUCHUNGSGRUPPE = B1.BUCHUNGSGRUPPE AND H1.LFDNR = B1.LFDNR
AND (H1.BUCHUNGSGRUPPE = '8888' OR (H1.BUCHUNGSGRUPPE > 5999 AND H1.BUCHUNGSGRUPPE < 7100 AND B1.SICHERHEITBEZUG = 1))) HD,
(SELECT TO_CHAR(ERFASSDATUM,'YYYY/MM') DATUM, SUM(BETRAG) GELDEINGAENGE_INSG
FROM HIST_VIEW H2,FORD_VIEW F1
WHERE ((F1.GLAEUBIGERNR= H2.GLAEUBIGERNR AND F1.FORDNR=H2.FORDNR AND F1.FORDERGNR=H2.FORDERGNR) OR
F1.MAHN_NUM = H2.MAHN_NUM) AND H2.BUCHUNGSGRUPPE = '8888'
GROUP BY TO_CHAR(ERFASSDATUM,'YYYY/MM') ) HA2,
(SELECT TO_CHAR(ERFASSDATUM,'YYYY/MM') DATUM, SUM(BETRAG) VERWERTUNGSERLOESE
FROM HIST_VIEW H3, BUCHUNGSSCHL B3,FORD_VIEW F2
WHERE ((F2.GLAEUBIGERNR=H3.GLAEUBIGERNR AND F2.FORDNR=H3.FORDNR
AND F2.FORDERGNR=H3.FORDERGNR) OR F2.MAHN_NUM = H3.MAHN_NUM) AND B3.STORNOMM=0
AND H3.BUCHUNGSGRUPPE = B3.BUCHUNGSGRUPPE AND
H3.LFDNR = B3.LFDNR AND H3.BUCHUNGSGRUPPE > 5999
AND H3.BUCHUNGSGRUPPE < 7100 AND (B3.SICHERHEITBEZUG = 1 OR B3.NACHMIETVERTRAGE =1)
GROUP BY TO_CHAR(ERFASSDATUM,'YYYY/MM')) HA3
WHERE HD.DATUM=HA2.DATUM (+)
AND HD.DATUM=HA3.DATUM (+)
ORDER BY DATUM ASC )
ORA-00907: missing right parenthesisIf you format your code it makes it far easier to spot mistakes...
WITH HIST_VIEW AS (SELECT GLAEUBIGERNR,FORDNR,FORDERGNR,MAHN_NUM,BUCHUNGSGRUPPE,LFDNR,STORNOMM,ERFASSDATUM,BETRAG
FROM TRANS_HIST H
WHERE ERFASSDATUM >=TO_DATE('01.10'||TO_CHAR(ADD_MONTHS(SYSDATE,-9),'YYYY')||' 00.00.00','DD.MM.YYYY HH24:MI:SS')
AND ( H.BUCHUNGSGRUPPE = '8888'
OR (H.BUCHUNGSGRUPPE > 5999 AND H.BUCHUNGSGRUPPE < 7100)
FORD_VIEW AS (SELECT F.GLAEUBIGERNR,F.FORDNR,F.FORDERGNR,A.MAHN_NUM
FROM FRD_ACCT F,ANS_PRCH A
WHERE F.GLAEUBIGERNR=A.GLAEUBIGERNR(+)
AND F.FORDNR=A.FORDNR(+)
AND F.FORDERGNR=A.FORDERGNR(+)
AND NVL(F.INDIVIDUALFLAG,0)=0
AND A.RANGMM=1
SELECT HD.DATUM DATUM
,HA2.GELDEINGAENGE_INSG-NVL(HA3.VERWERTUNGSERLOESE,0) GELDEINGANG
,HA3.VERWERTUNGSERLOESE
FROM (SELECT DISTINCT(TO_CHAR(ERFASSDATUM,'YYYY/MM')) DATUM
FROM HIST_VIEW H1
,BUCHUNGSSCHL B1
WHERE B1.STORNOMM=0
AND H1.BUCHUNGSGRUPPE = B1.BUCHUNGSGRUPPE
AND H1.LFDNR = B1.LFDNR
AND ( H1.BUCHUNGSGRUPPE = '8888'
OR (H1.BUCHUNGSGRUPPE > 5999 AND H1.BUCHUNGSGRUPPE < 7100 AND B1.SICHERHEITBEZUG = 1)
) HD,
(SELECT TO_CHAR(ERFASSDATUM,'YYYY/MM') DATUM
,SUM(BETRAG) GELDEINGAENGE_INSG
FROM HIST_VIEW H2
,FORD_VIEW F1
WHERE (
( F1.GLAEUBIGERNR= H2.GLAEUBIGERNR
AND F1.FORDNR=H2.FORDNR
AND F1.FORDERGNR=H2.FORDERGNR
OR
F1.MAHN_NUM = H2.MAHN_NUM
AND H2.BUCHUNGSGRUPPE = '8888'
GROUP BY TO_CHAR(ERFASSDATUM,'YYYY/MM')
) HA2,
(SELECT TO_CHAR(ERFASSDATUM,'YYYY/MM') DATUM
,SUM(BETRAG) VERWERTUNGSERLOESE
FROM HIST_VIEW H3
,BUCHUNGSSCHL B3
,FORD_VIEW F2
WHERE (
( F2.GLAEUBIGERNR=H3.GLAEUBIGERNR
AND F2.FORDNR=H3.FORDNR
AND F2.FORDERGNR=H3.FORDERGNR
OR
F2.MAHN_NUM = H3.MAHN_NUM
AND B3.STORNOMM=0
AND H3.BUCHUNGSGRUPPE = B3.BUCHUNGSGRUPPE
AND H3.LFDNR = B3.LFDNR
AND H3.BUCHUNGSGRUPPE > 5999
AND H3.BUCHUNGSGRUPPE < 7100
AND (B3.SICHERHEITBEZUG = 1 OR B3.NACHMIETVERTRAGE =1)
GROUP BY TO_CHAR(ERFASSDATUM,'YYYY/MM')
) HA3
WHERE HD.DATUM=HA2.DATUM (+)
AND HD.DATUM=HA3.DATUM (+)
ORDER BY DATUM ASC
) <--- What's this doing on the end?Remove that last bracket and you should be ok.
I took the liberty of putting the subquery factoring at the beginning, so see if that works. -
Report with multiplying columns and WITH clause
Hello
I saw sth strange in my report. I assume that it could happens very often.
I have report with few columns which two of them ar most complicated (many joins subqueries aggreagations on joined values etc.) These two columns (i.e C3,C4) should be multiplied (C3*C4).
When i do pure report without multiplying only columns C1,C2,C3,C4 everything is ok - duration about 15 sec. but... when I put next column on report which multiply these columns (in Answers C5=C3*C4)
I wait 3-4 minutes and my database hungs :(. After investigation I saw that in first case to databese goes pure "SELECT" statement it means:
"Select ... as C1, ... as C2, max(...) as C3, sum(xxx)... C4 from yyy,sss,ttt WHERE aaa"
but in second case BI uses WITH clause it means:
WITH SAWITH0 AS
( Select ... as C1, ... as C2, max(...) as C3, sum(xxx)... C4 from yyy,sss,ttt WHERE aaa )
SELECT SAWITH0.C1 as C1,
SAWITH0.C2 as C2,
SAWITH0.C3 as C3,
SAWITH0.C4 as C4,
SAWITH0.C3*SAWITH0.C4 as C5 FROM SSS
and this statement is long runninq query and kills my database :(.
I checked that SQL like this:
Select ... as C1, ... as C2, max(...) as C3, sum(xxx)... C4, max(...)*sum(xxx)... As C5 from yyy,sss,ttt WHERE aaa" -
runs few times faster than that above
I know that I can do this multiply in business model layer but sometimes users can multiply(or other operations) on columns in reports without my knowledge and it kills my db :(. Where is bug? Why SQLs with WITH clause takes so much db time?
Thank you for each kind of helpWITH clause or Subquery Factoring allows the set of data to be reused multiple times within the SQL. Oracle will usually materialize the data into a temporary table (you will see it if you take an explain plan of the SQL).
I would be surprised if it was the actual WITH clause that was causing the performance issue, however you can test this by turning the WITH clause feature off. Go to the Physical model, right mouse click on your Database > Properties > Features Tab, scroll down to WITH_CLAUSE_SUPPORTED and switch it off.
I'd be interested to know if you do see actual improvement.
Good Luck. -
Hi,
I was going through some docs on using WITH clause in curosr...but coulcn't understand.
I was going through existing code for customization, that has 'WITH' clause.
I'm trying to understand below piece of code.
could you let me know what the below code is about..
CURSOR CUR_CRK
IS
WITH PTLPM_WITH AS
(SELECT
/*+ INDEX(P_TR_LOAN_PAST_MONTHLY PK_P_TR_LOAN_PAST_MONTHLY) */
FROM INF.P_TR_LOAN_PAST_MONTHLY
WHERE POST_DATE =P_POST_DATE
AND TREND_GROUP_ID = 'M'
AND APPL_ID IN ('FL','LN')
UIGL_INF_WITH AS
(SELECT * FROM INF.U_IM_GALL_LOAN
XHCC_INF_WITH as
(SELECT * FROM DWC.XREF_HIER_COST_CENTER_11SEP12 --INF.XREF_HIER_COST_CENTER
)Thanks.Perhaps a simple example will make it clear...
SQL> ed
Wrote file afiedt.buf
1 select e.empno, e.ename, d.dname
2 from (select * from emp) e
3 join (select * from dept) d
4* on (e.deptno = d.deptno)
SQL> /
EMPNO ENAME DNAME
7369 SMITH RESEARCH
7499 ALLEN SALES
7521 WARD SALES
7566 JONES RESEARCH
7654 MARTIN SALES
7698 BLAKE SALES
7782 CLARK ACCOUNTING
7788 SCOTT RESEARCH
7839 KING ACCOUNTING
7844 TURNER SALES
7876 ADAMS RESEARCH
7900 JAMES SALES
7902 FORD RESEARCH
7934 MILLER ACCOUNTING
14 rows selected.Ok, a bit of a nonsense query in itself, but it's demonstrating that we have two subqueries that we are getting our data from.
Now, writing the same query using a WITH clause...
SQL> ed
Wrote file afiedt.buf
1 with e as (select * from emp)
2 ,d as (select * from dept)
3 select e.empno, e.ename, d.dname
4* from e join d on (e.deptno = d.deptno)
SQL> /
EMPNO ENAME DNAME
7369 SMITH RESEARCH
7499 ALLEN SALES
7521 WARD SALES
7566 JONES RESEARCH
7654 MARTIN SALES
7698 BLAKE SALES
7782 CLARK ACCOUNTING
7788 SCOTT RESEARCH
7839 KING ACCOUNTING
7844 TURNER SALES
7876 ADAMS RESEARCH
7900 JAMES SALES
7902 FORD RESEARCH
7934 MILLER ACCOUNTING
14 rows selected.As you can see, the subqueries have been moved out of the main query and put into the WITH clause, and then the main query just references those subqueries aliases.
In the above example, there's not much point in doing this, but in more complex queries, you may have a subquery that is used several times, in which case having it in the WITH clause means that that subquery is processed just once and used many times, (you can also look at the MATERIALIZE hint to help improve performance with such subqueries if necessary)
The difficulty with finding this in the documentation is because you will no doubt be trying to search for "WITH", which isn't a very good search term to be using as it's used in the english language too much for an accurate hit... so... when you learn it's called "Subquery Factoring" (because you are factoring out the subqueries from the main query), it then becomes easier to find...
http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#i2161315
... and you see it's included as part of the documentation for the SQL SELECT statement. -
Using full outer join of subqueries named using with clause
Hi,
I am trying to create a view which is having 2 subqueries vol1 & vol2 with WITH clause. I am joining those 2 subqueries in the main query with FULL OUTER JOIN.
When i compile that view in a tool like pl/sql developer, It has been compiled successfully.
But when i call the view creation script from SQL command prompt, It is throwing error as
from vol1 FULL JOIN vol2 o ON (vol1.ct_reference = vol2.ct_reference and vol1.table_name = vol2.table_name
ERROR at line 29:
ORA-00942: table or view does not exist
Kindly advise whats going wrong.that's line 29. Maybe you get a better idea if you strip your operation of all the unneccessary elements until it works.
There are some known bugs with subquery factoring (aka with clause) and also with ANSI join syntax, but it is hard to tell what happens here based on your description. But one thing is strange - if it is not a result of formatting (not formatting): I would expect the asterisk beneath the unknown table and not beneath the key word FULL.
P.S.: my editor makes me think it's rather a proportional font thing. Have I already said that I don't like proportional font for SQL code examples? -
With Clause in Pro*C?
Is it possible to use version 9's with clause (aka
subquery factoring) within pro*C? Queries that work
fine in SQL*Plus cause the pre-compiler to fail. For
example:
SQL> with test as (select 1 one from dual)
2 select * from test
3 /
ONE
1
Taking the same query and embedding it in a Pro*C program,
produces the following results:
EXEC SQL
with test as (select 1 one from dual)
SELECT *
INTO :n
FROM test;
$ proc ora_test.pc
Pro*C/C++: Release 9.2.0.5.0 - Production on Mon Dec 20 13:27:16 2004
Copyright (c) 1982, 2002, Oracle Corporation. All rights reserved.
System default option values taken from: /ora/product/9.2.0/precomp/admin/pcscfg.cfg
Syntax error at line 20, column 7, file ora_test.pc:
Error at line 20, column 7 in file ora_test.pc
with test as (select 1 one from dual)
......1
PCC-S-02201, Encountered the symbol "with" when expecting one of the following:
for, register, at, close, commit, connect, declare, describe,
execute, fetch, open, prepare, rollback, select, whenever,
alter, audit, comment, create, delete, drop, get, grant,
insert, lock, noaudit, rename, revoke, set, update, validate,
arraylen, allocate, cache, call, collection, context,
deallocate, enable, free, lob, object, savepoint, analyze,
explain, truncate,
The symbol "alter," was substituted for "with" to continue.
Parser error at line 22, column 15, file ora_test.pc:
Error at line 22, column 15 in file ora_test.pc
INTO :n
..............1
PCC-S-02206, Host variables are not permitted within a DDL statement
Error at line 0, column 0 in file ora_test.pc
PCC-F-02102, Fatal error while doing C preprocessingI suppose that the 'with clause ' is a new feature of ORACLE9 ? Well, lets dive in the fabulous world of ORACLE development :
When the parser of ORACLE9 has been enhanced to accept ORACLE9 new features and syntax (especially the SQL1999 join syntax), the parser of PRO*C and PRO*Cobol still stayed at the ORACLE8 syntax level. The parser is at the Precompiler side.
This means that you have NO CHANCE to even precompile a ORACLE9 syntax SQL statement with any precompiler tool.
This is not a bug (from metalink) because the Oracle Development project for the new parser has not been started yet. I the product is not developped, it is not a bug , and i understand that they cannot correct the flaw.
This is not corrected in any known ORACLE10 version - just because the project has not yet started !!!
The only workaround that i have found consists in using a View which contains the syntax. This works fine for JOIN queries, i do not have tested for the 'with clause'.
Maybe other workarounds available at the metalink side.
Regards
Frederic
Maybe you are looking for
-
hi i developed one report and one bapi (to create sale order with ref to contract) every thing working fine. now my client asked he want to call bapi program from report because my report output is input to bapi for this i maintained check box for ev
-
I am trying to sort out a friends macbook that has been subjected to a scam attack. I am a pc user so am struggling here a bit. Her machine seems to have been attacked by a program called MacSecurity. It is telling her that she has a number of vir
-
Hi! It has been 24 hours now since I've installed Lion on my iMac. Previously with Snow Leopard everything worked smoothly but now every 30 min and sometimes less than that I get kernel panics that keep me from using my computer. This is the report g
-
Hi i am getting error in xml form builder
hi i created edit,renderlistitem,show i haveadded buttons from extras-buttons i am getting error as Error:Edit form doenot contain save button or link what could be the reason how to solve it pls reply
-
Subclass instance not created during runtime
Hi Experts, For an existing standard class a subclass was created and during runtime the me object reference points to the subclass name there by allowing the subclass additional/custom methods to be triggered. We have done service pack upgrade in th