Recursive subquery
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ás
Use 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.
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.... -
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,
PeterWorks 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. -
PARTITION RANGE SUBQUERY - Access path
Below quote is from Oracle product documentation.
<quote>
If the table with the WHERE predicate is relatively small compared to the partitioned table, and the expected reduction of records or partitions for the partitioned table is significant, Oracle will perform dynamic partition pruning using a recursive subquery
</quote>
http://download.oracle.com/docs/cd/B19306_01/server.102/b14223/parpart.htm#sthref215
create table t(
x number,
y number,
z number
) partition by range(z)
partition p_10 values less than ( 11),
partition p_20 values less than ( 21),
partition p_30 values less than ( 31),
partition p_40 values less than ( 41),
partition p_50 values less than ( 51),
partition p_60 values less than ( 61),
partition p_70 values less than ( 71),
partition p_80 values less than ( 81),
partition p_90 values less than ( 91),
partition p_100 values less than ( 101)
create table t1
as
select mod(rownum,10) as id,
username ,
sysdate as dt
from all_users;
insert /*+ append */ into t
select level,level,10
from dual
connect by level <= 1000000;
commit;
insert /*+ append */ into t select x,y,20 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,30 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,40 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,50 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,60 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,70 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,80 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,90 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,100 from t partition (p_10);
commit;
begin
dbms_stats.gather_table_Stats(user,'T1');
dbms_stats.gather_table_stats(ownname=>user,tabname=>'T',degree=>16);
end;
select /*+ use_hash(t,t1) */ t.*
from t, t1
where t.z = t1.id
and t1.username ='SCOTT'
call count cpu elapsed disk query current rows
Parse 1 0.03 0.67 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.65 0.65 0 2507 0 0
total 3 0.68 1.32 0 2507 0 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 100
Rows Row Source Operation
0 HASH JOIN (cr=2510 pr=0 pw=0 time=653031 us)
1 TABLE ACCESS FULL T1 (cr=3 pr=0 pw=0 time=59 us)
1000000 PARTITION RANGE SUBQUERY PARTITION: KEY(SUBQUERY) KEY(SUBQUERY) (cr=2507 pr=0 pw=0 t
1000000 TABLE ACCESS FULL T PARTITION: KEY(SUBQUERY) KEY(SUBQUERY) (cr=2504 pr=0 pw=0 t
select /*+ use_nl(t,t1) */ t.*
from t, t1
where t.z = t1.id
and t1.username ='SCOTT'
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.12 0.12 0 2506 0 0
total 3 0.12 0.12 0 2506 0 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 100
Rows Row Source Operation
0 NESTED LOOPS (cr=2506 pr=0 pw=0 time=123836 us)
1 TABLE ACCESS FULL T1 (cr=3 pr=0 pw=0 time=53 us)
0 PARTITION RANGE ITERATOR PARTITION: KEY KEY (cr=2503 pr=0 pw=0 time=123777 us)
0 TABLE ACCESS FULL T PARTITION: KEY KEY (cr=2503 pr=0 pw=0 time=123761 us)
Questions_
1) what is the significant in having this PARTITION RANGE SUBQUERY access path in Oracle 10g? Even reading documentation, still unclear.
Edited by: Rajeshwaran on Nov 15, 2010 8:05 AMYep..Here is the code.
create table t(
x number,
y number,
z number
) partition by range(z)
partition p_10 values less than ( 11),
partition p_20 values less than ( 21),
partition p_30 values less than ( 31),
partition p_40 values less than ( 41),
partition p_50 values less than ( 51),
partition p_60 values less than ( 61),
partition p_70 values less than ( 71),
partition p_80 values less than ( 81),
partition p_90 values less than ( 91),
partition p_100 values less than ( 101)
create table t1
as
select mod(rownum,10) as id,
username ,
sysdate as dt
from all_users;
insert /*+ append */ into t
select level,level,10
from dual
connect by level <= 1000000;
commit;
insert /*+ append */ into t select x,y,20 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,30 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,40 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,50 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,60 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,70 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,80 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,90 from t partition (p_10);
commit;
insert /*+ append */ into t select x,y,100 from t partition (p_10);
commit;
begin
dbms_stats.gather_table_Stats(user,'T1');
dbms_stats.gather_table_stats(ownname=>user,tabname=>'T',degree=>16);
end;
select /*+ use_hash(t,t1) */ t.*
from t, t1
where t.z = t1.id
and t1.username ='SCOTT'
call count cpu elapsed disk query current rows
Parse 1 0.03 0.67 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.65 0.65 0 2507 0 0
total 3 0.68 1.32 0 2507 0 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 100
Rows Row Source Operation
0 HASH JOIN (cr=2510 pr=0 pw=0 time=653031 us)
1 TABLE ACCESS FULL T1 (cr=3 pr=0 pw=0 time=59 us)
1000000 PARTITION RANGE SUBQUERY PARTITION: KEY(SUBQUERY) KEY(SUBQUERY) (cr=2507 pr=0 pw=0 t
1000000 TABLE ACCESS FULL T PARTITION: KEY(SUBQUERY) KEY(SUBQUERY) (cr=2504 pr=0 pw=0 t
select /*+ use_nl(t,t1) */ t.*
from t, t1
where t.z = t1.id
and t1.username ='SCOTT'
call count cpu elapsed disk query current rows
Parse 1 0.00 0.00 0 0 0 0
Execute 1 0.00 0.00 0 0 0 0
Fetch 1 0.12 0.12 0 2506 0 0
total 3 0.12 0.12 0 2506 0 0
Misses in library cache during parse: 1
Optimizer mode: ALL_ROWS
Parsing user id: 100
Rows Row Source Operation
0 NESTED LOOPS (cr=2506 pr=0 pw=0 time=123836 us)
1 TABLE ACCESS FULL T1 (cr=3 pr=0 pw=0 time=53 us)
0 PARTITION RANGE ITERATOR PARTITION: KEY KEY (cr=2503 pr=0 pw=0 time=123777 us)
0 TABLE ACCESS FULL T PARTITION: KEY KEY (cr=2503 pr=0 pw=0 time=123761 us) -
Querying all_tab_columns
Hi all,
This is a "my query takes too long" question but it relates to the ALL_TAB_COLUMNS view.
I'm trying to generate some basic DML scripts from a large number of tables (insert/update) the cheating way by selecting columns from all_tab_columns
e.g.
select 'insert into '||table_name||' ('
from all_tables
where table_name = 'TABLE_NAME_HERE'
union all
select column_name||','
from all_tab_columns
where table_name = 'TABLE_NAME_HERE'
--etc.however, I want the column names all on one line.
so I have the following, which I imagine should create the column_name's on one line but it "runs for ages"
select sys_connect_by_path(column_name,', ') c
from all_tab_columns
where owner = 'WHITEHAT'
and table_name = 'FOO'
and connect_by_isleaf = 1
start with column_id = 1
connect by column_id = prior column_id + 1I am using 10gR2 so unfortunately I can't use recursive subquery factoring just yet, although that equivalent runs quickly as expected on our 11g environment:
with t (column_name, column_id)
as (select cast(column_name as varchar2(4000)), column_id
from all_tab_columns
where owner = 'WHITEHAT'
and table_name = 'FOO'
and column_id = 1
UNION ALL
SELECT cast(t.column_name||', '||atc.column_name as varchar2(4000))
,atc.column_id
from t
,all_tab_columns atc
where owner = 'WHITEHAT'
and table_name = 'FOO'
and atc.column_id = t.column_id + 1
select column_name
from (
select column_name, column_id, max(column_id) over () max_col_id
from t
where column_id = max_col_idwhat am I doing wrong?Hi,
WhiteHat wrote:
... so I have the following, which I imagine should create the column_name's on one line but it "runs for ages"
select sys_connect_by_path(column_name,', ') c
from all_tab_columns
where owner = 'WHITEHAT'
and table_name = 'FOO'
and connect_by_isleaf = 1
start with column_id = 1
connect by column_id = prior column_id + 1... what am I doing wrong?The WHERE clause is applied after the START WITH and CONNECT BY clauses are complete.
So you're starting with one row from every table. Let's say you have a small database, with 1000 tables. On LEVEL=1 you have 1000 rows. Then you're connecting every column with column_id=2 to each of those those 1000 rows. Almost every table will have a column with column_id=2, so you'll have 1,000,000 rows on LEVEL=2. I think you can see where this is going.
Don't use a WHERE clause to get the right table. Put the conditions you now have in the WHERE clause (or equivalent conditions, except for "connect_by_isleaf = 1") in the START WITH and CONNECT BY clauses, instead, or apply the WHERE clause in a sub-query, first, like this:
WITH universe AS
SELECT column_name
, column_id
FROM all_tab_columns
WHERE owner = 'WHITEHAT'
AND table_name = 'FOO'
SELECT SYS_CONNECT_BY_PATH (column_name, ',') AS c
FROM universe
WHERE CONNECT_BY_ISLEAF = 1
START WITH column_id = 1
CONNECT BY column_id = 1 + PRIOR column_id
; -
What is "with" and "Connecty By" in Oracle SQL
Hello All,
I'm Just going through the forum topics, I have seen sql queries starts like "with t as" and at the end it closes like "connect ". I have seen this kind for normal queries also. Please let me know what is the "with" concept and when do we use that?
Thanks in Advance!!!And in 11gR2 you can combine the two with the new feature Recursive Subquery Refactoring (well sort of, because you don't need the connect by bit)
I'd link to the official docs but they seem to be suffering intermittent issues at the moment so:
http://technology.amis.nl/blog/6267/oracle-rdbms-11gr2-new-style-hierarchical-querying-using-recursive-subquery-factoring
http://technology.amis.nl/blog/6104/oracle-rdbms-11gr2-goodbye-connect-by-or-the-end-of-hierarchical-querying-as-we-know-it -
SQL query, generating several rows by a value in a field
I am using Oracle database. Imaging I have a table with a row as following
col1 | col2 | col3
'Str1' | 'Str2' | 4
The value from col3=4 should generate 4 rows as following:
col1 | col2 | col3
'Str1' | 'Str2' | 1
'Str1' | 'Str2' | 2
'Str1' | 'Str2' | 3
'Str1' | 'Str2' | 4
After several hours in front of the screen and stil no luck - how can I create such a select query???You're mixing up the 'standard' WITH clause and Recursive Subquery Factoring (which NEEDS a UNION ALL) (see: http://docs.oracle.com/cd/E11882_01/server.112/e26088/statements_10002.htm#i2129904).
This should work on 10.2:
SQL> select * from v$version;
BANNER
Oracle Database 10g Enterprise Edition Release 10.2.0.4.0 - 64bi
PL/SQL Release 10.2.0.4.0 - Production
CORE 10.2.0.4.0 Production
TNS for Linux: Version 10.2.0.4.0 - Production
NLSRTL Version 10.2.0.4.0 - Production
SQL> with t as (select 'str1' col1, 'str2' col2, 4 col3 from dual
2 )
3 select col1
4 , col2
5 , level col3
6 from t
7 connect by level <= col3;
COL1 COL2 COL3
str1 str2 1
str1 str2 2
str1 str2 3
str1 str2 4
See here as well: http://technology.amis.nl/2009/09/01/oracle-rdbms-11gr2-goodbye-connect-by-or-the-end-of-hierarchical-querying-as-we-know-it/ -
What is API? Why we use in oracle Apps? Please explain me little bit.
Hi,
Can you please explain me step by step for what is API. why we use and where we have to use? please explain me.
Regards,
RajAnd in 11gR2 you can combine the two with the new feature Recursive Subquery Refactoring (well sort of, because you don't need the connect by bit)
I'd link to the official docs but they seem to be suffering intermittent issues at the moment so:
http://technology.amis.nl/blog/6267/oracle-rdbms-11gr2-new-style-hierarchical-querying-using-recursive-subquery-factoring
http://technology.amis.nl/blog/6104/oracle-rdbms-11gr2-goodbye-connect-by-or-the-end-of-hierarchical-querying-as-we-know-it -
I have the below data set -
Order_id Item Qty
1 A1 3
2 A2 2
3 A3 3
My desired output (With only one SQL query) is mentioned below-
Order_id Item Qty
1 A1 1
1 A1 1
1 A1 1
2 A2 1
2 A2 1
3 A3 1
3 A3 1
3 A3 1
How do I do this?Another way would be :
SQL> with sample_data as (
2 select 1 order_id, 'A1' item, 3 qty from dual union all
3 select 2, 'A2', 2 from dual union all
4 select 3, 'A3', 3 from dual
5 )
6 select t1.order_id
7 , t1.item
8 , t2.column_value as qty
9 from sample_data t1
10 , table(
11 cast(
12 multiset(
13 select 1 from dual connect by level <= t1.qty
14 ) as sys.odcinumberlist
15 )
16 ) t2
17 ;
ORDER_ID ITEM QTY
1 A1 1
1 A1 1
1 A1 1
2 A2 1
2 A2 1
3 A3 1
3 A3 1
3 A3 1
8 rows selected
or, using recursive subquery factoring (11.2) :
SQL> with sample_data as (
2 select 1 order_id, 'A1' item, 3 qty from dual union all
3 select 2, 'A2', 2 from dual union all
4 select 3, 'A3', 3 from dual
5 ),
6 dataset (order_id, item, qty, sofar) as
7 (
8 select order_id
9 , item
10 , qty
11 , 1
12 from sample_data
13 union all
14 select order_id, item, qty, sofar+1
15 from dataset
16 where sofar < qty
17 )
18 search depth first by order_id set seq
19 select order_id, item, 1 as qty
20 from dataset
21 ;
ORDER_ID ITEM QTY
1 A1 1
1 A1 1
1 A1 1
2 A2 1
2 A2 1
3 A3 1
3 A3 1
3 A3 1
8 rows selected -
I have a query
Eg: select id,name from user
where user.id in ('a7','a6','a3',....); --- ID's are in different order not, in ascending or descending
the output of the above query is something like
id name
a3 a3_name
a7 a7_name
a6 a6_name
But I would like the output to be in the order input was given inside
a7 a7_name
a6 a6_name
a3 a3_name
How do we do this?user651347 wrote:
I had a list given with 300 users and neither in ASC or DESC order
so we need to order this the way it was given or in the select ... in (); statementOk. Did you mathematical "set" theory at school? Familiar with Venn diagrams?
If you are, let's look at two sets of values.... (1,2,3,4) and (4,3,2,1)....
As a Venn diagram you'd end up drawing those two sets as:-
Set A Set B
# # 2 # #
# # 1 # #
# # 4 # #
# # 3 # #
####### #######They are identical sets and there is no order to them.
You can even do this in SQL, to see if there is a difference in the two sets...
SQL> create or replace type myset as table of number;
2 /
Type created.
SQL> select myset(1,2,3,4) multiset except myset(4,3,2,1) as diff from dual;
DIFF
MYSET()As you can see, it doesn't matter what order the elements of the set are specified in. As a SET, they are considered identical. The order of the elements when specifying the sets makes no difference.
So, in your query, you can pass your elements to you IN operator in any order you like... but those elements are a SET of data... they have no order, except in the way you read them. Oracle see's no order to them, and cannot consider there to be an order to them.
Therefore, if you need an order to the elements, using a SET of data is not the right approach as it doesn't contain an order. You would need to specify a set of data that contains information about the order, and you'd usually do that by inserting the elements into a table (Global Temporary Table perhaps?) with some additional column containing details of the order, and then in your query, you would use the ORDER BY clause to order on that additional ordering information.
The only way to guarantee the order of output from an SQL statement is to specify an ORDER BY clause. ^1^
^1 There are a few exceptions such as hierarchical queries or data generating queries such as those with recursive subquery factoring or model clauses if used in certain ways^ -
Find all child tables - validate sql
I have a table (tabA), In tabA i have a column (id) which is part of primary key
Question: I need to know all the tables which have foreign keys refererring to tabA.id
I used the following sql, please let me know if this is correct:
select table_name
from dba_constraints
where (r_constraint_name) in ( select constraint_name
from dba_constraints
where table_name = 'tabA'
and constraint_type in ( 'P', 'U' ) );On 11.2 you could try recursive subquery factoring:
select *
from ( with the_constraints( table_name
, constraint_name
, r_constraint_name
, lvl
as ( select a.table_name
, a.constraint_name
, a.r_constraint_name
, 1 lvl
from all_constraints a
where a.table_name = 'tabA'
and a.constraint_type = 'P'
union all
select c.table_name
, nvl(( select constraint_name
from all_constraints
where table_name = c.table_name
and constraint_type = 'P'
, c.constraint_name
, c.r_constraint_name
, lvl+1
from the_constraints p,
all_constraints c
where p.constraint_name = c.r_constraint_name
and c.constraint_type = 'R'
search depth first by table_name set seq
cycle table_name set is_cycle to 1 default 0
select rownum rn
, lpad('>', (lvl-1)*2, '-')||table_name relation
, c.*
from the_constraints c
order by rn desc; -
Hi. I'm wondering if one could solve a Sudoku puzzle with a SQL query given the initial configuration of the Sudoku is stored in a database table. Suppose I have a database table named InitSudoku storing the initial configuration of a 5x5 Sudoku. Each row in the table indicates which number (1 to 25) is initially placed in which square of the puzzle. For example, the row (15,3,9) means the number 15 is initially placed in the square at the 3rd row and the 9th column of the puzzle. What I would like to get is a result set that would give me a completion of the Sudoku. Does anyone think that is doable strictly within SQL with one or more queries (without using a procedural language like C or Java, which would require coding up an algorithm of solving Sudoku)?
Thanks.The same guru has improved on this solution in 11gr2:
[http://technology.amis.nl/blog/6404/oracle-rdbms-11gr2-solving-a-sudoku-using-recursive-subquery-factoring|http://technology.amis.nl/blog/6404/oracle-rdbms-11gr2-solving-a-sudoku-using-recursive-subquery-factoring]
[http://tonyhasler.wordpress.com] -
ORA-32031: illegal reference of a query name in WITH clause
Oracle tutorial : http://www.oracle.com/technology/pub/articles/hartley-recursive.html#4
When Executing this Query 6: Using a Recursive WITH Clause
WITH C (CNO, PCNO, CNAME) AS
(SELECT CNO, PCNO, CNAME -- initialization subquery
FROM COURSEX
WHERE CNO = 'C22' -- seed
UNION ALL
SELECT X.CNO, X.PCNO, X.CNAME -- recursive subquery
FROM C, COURSEX X
WHERE C.PCNO = X.CNO)
SELECT CNO, PCNO, CNAME
FROM C;
Error: ORA-32031: illegal reference of a query name in WITH clause
kindly suggest what need to do in case of recursion using subquerySCOTT@orcl> ed
Wrote file afiedt.buf
1 with c as
2 (
3 select empno,ename from emp
4 where deptno=20
5 union all
6 select c.empno,c.ename from emp c
7 where c.deptno=30
8 )
9* select * from c
SCOTT@orcl> /
EMPNO ENAME
7566 xx
7788 xx
7876 xx
7902 xx
7499 xx
7521 xx
7654 xx
7698 xx
7844 xx
7900 xx
10 rows selected.
SCOTT@orcl> ed
Wrote file afiedt.buf
1 with emp as
2 (
3 select empno,ename from emp
4 where deptno=20
5 union all
6 select c.empno,c.ename from emp c
7 where c.deptno=30
8 )
9* select * from emp
SCOTT@orcl> /
select empno,ename from emp
ERROR at line 3:
ORA-32031: illegal reference of a query name in WITH clause
SCOTT@orcl>You can not use the same table name alongwith WITH clause's cursor name. See as above if i says with C as... its works; but if i says with emp as... it returned ora-32031, because it is the name of table.
HTH
Girish Sharma -
hi
select 1 slno, 1000 Amount , 0.12 Int_Rate, 1000*0.12 IntAmt from dual
union
select 2 slno, 1000 Amount , 0.13 Int_Rate ,1120 * 0.13 from dual
SLNO AMOUNT INT_RATE INTAMT
1 1000 0.12 120
2 1000 0.13 145.6
Column 120 is the product of amount*int_rate(1000*0.12)
Column 145.6 is the product of amount*int_rate(1000*0.12)*int_rate(1000*0.13)
Can i get the help from somebody to compute using an analytical function to get the result
Thanks in Advanceuser639304 wrote:
Hi,
That's great Sven W. In SQL, we have something to sum the values of rows, but we have nothing for the product of values of rows (or, at least, if something exist to express directly the product of numbers, we don't often use it) . So I was thinking to how use the existing functionalities of SQL in order to have the product of values in a given column, and I was thinking to the ln and exp functions. But I didn't arrive to the point where Sven W. has arrived. Sven W. has used the formula:
x1 * x2 * ... * xn = exp(ln(x1) + ln (x2) + ... + ln(xn)), in other terms, roughly speaking,
Product of values = exp(Sum of the ln of these values).Thanks for the explaination. I didn't had a proper idea how to write one myself. ;)
A minor issue with this solution is that it might be a little CPU intensive. For example I had to add rounding, because the floating point math involved led to rounding issues.
So if we need this often, it could be better to build our own aggregate_multiplication function. This is less complicated then one often thinks.
Oh and here is the solution using a recursive with clause. I build it upon nicosas version, but changed the math to be consistent with my previous examples.
Op wasn't very clear about the math behind and I think that led to much confusion.
with t as (
select 1 slno, 1000 Amount , 0.12 Int_Rate from dual
union all
select 2 slno, 0 Amount , 0.13 Int_Rate from dual
union all
select 3 slno, 0 Amount , 0.14 Int_Rate from dual
order by slno -- this is important
------ end of sample data ------
------ This removes the gap-problem, by introducing a sequential row number
, t2 as (select rownum rn, slno, Amount, Int_Rate
from t)
------ trec below is a recursive with clause (AKA recursive subquery factoring) ------
trec(rn, slno,amount,int_rate) as
select rn,slno,amount*(1+int_rate),int_rate
from t2 base
where rn=1
union all
select t3.rn,t3.slno,trec.amount*(1+t3.int_rate),t3.int_rate
from t2 t3
join trec on t3.rn=trec.rn+1
------ just query the recursive with clause ------
select * from trec
RN SLNO AMOUNT INT_RATE
1 1 1120 0,12
2 2 1265,6 0,13
3 3 1442,784 0,14 This is the important line
trec.amount*(1+t3.int_rate)
Essentially this puts the amount from the previous row up for multiplication with interest from the current row. And sets it a the new amount.
Edited by: Sven W. on Aug 17, 2012 3:07 PM - added with clause solution
Edited by: Sven W. on Aug 17, 2012 3:10 PM - Typo correction
Maybe you are looking for
-
Ok, so i originally installed itunes on an external hard drive (G drive) and not my PC. So my itunes runs completely from my external and that how I like it. Well over time it got full so I bought and moved all my media over to a bigger 2TB external
-
Java cmd doesn't find a created package during execution
Hi all, I created a package and modified the CLASSPATH in order to compile a program using my package. The compilation passed without errors nor warnings. Problem: When I invoked my program by using the following cmd line: java <Main Class Name> I go
-
Why does 1 cd appear more than once on the ipod
Hi I have a Classic ipod and use Windows 7; I have a couple of items which are appearing more than once on the ipod but only once on the laptop
-
Lightroom Catalog mix-up. Help please?
I am struggling hard, and failing, to make a new master catalog from 2 earlier, differing, ones. I have an iMac, Lr 5.6, and import into date folders in My Lightroom Folder (in Pictures). I know how to export folders as a catalog, I think, but seem u
-
Why no 'A5' option in page sizes when printing to pdf?
Hi there, Im running Windows XP Pro with Adobe Acrobat Professional 8.1.0 and I have tons of free disk space ;-) Ive created an A4 word document for work and they want it in A5 - when I try to print to A5 pdf, either from word direct, or from with Ad