Recursive Query
We have a structure like this
Parent Direct child
1 2
1 6
2 3
3 4
6 7
we want to generate the output as parent child relation if child is related to parent thro any hierarchy at any level
parent child
1 2(since 1->2)
1 6(since 1->6)
1 3(since 1 -> 2->3)
1 4(since 1->2->3->4)
1 7(since 1->6->7)
2 3(since 2->3)
2 4(since 2->3->4)
3 4(since 3-> 4)
6 7(since 6 -> 7)
assume all the numbers are employees
Could anyone please tell me how to go abt doing this?
Well here's one for free...
Oracle Database 10g Express Edition Release 10.2.0.1.0 - Production
SQL> SELECT CONNECT_BY_ROOT (parent) parent,
2 child,
3 '(since ' || SUBSTR (SYS_CONNECT_BY_PATH (
4 parent, ' -> '), 5) || ' -> ' || child || ')' reason
5 FROM table_name
6 CONNECT BY PRIOR child = parent;
PARENT CHILD REASON
1 2 (since 1 -> 2)
1 3 (since 1 -> 2 -> 3)
1 4 (since 1 -> 2 -> 3 -> 4)
1 6 (since 1 -> 6)
1 7 (since 1 -> 6 -> 7)
2 3 (since 2 -> 3)
2 4 (since 2 -> 3 -> 4)
3 4 (since 3 -> 4)
6 7 (since 6 -> 7)
9 rows selected.
SQL>
Similar Messages
-
Recursive Query without using connect_by
Hi All,
I have to find all the nodes related to a given node in a huge database table(billions of rows). Each node contains the following fields:
nodeID
TargetID
SourceID
TypeOfNode
Some XML metadata
The nodeID is the id for each node. My task is given a nodeID say 10 would be to retrieve this node from the database get the TargetID of this node. Then find all the nodes in the database that have their sourceID or targetID that equals this nodes TargetID. I have to do that recursively on each node that I found in the last query till I have the complete graph of all the nodes that are related to the node provided.
The method of how I am currently doing it is that I use the "connect_by" query in Oracle to find the tree of relationships in one direction then take the leaves of the tree and do a "connect by" in the opposite direction if I find any new roots I do a query in the reverse direction ..I keep doing that till I find no new roots or leaves. This works when the data is small but with the size of the data that I am quering at, I genrally end up with a OutOfMemory error and/otherwise get data back in about 4-5 days.
I was looking over the following SQL99 facility that I was hoping to use in order to get a controlled recursion on the data to do a transitive closure for graphs.
According to Stefan Wagner
"The last ISO standard for SQL, called SQL99 , provides a facility called recursive query. Writing a recursive query involves writing the query expression that one wants to recurse on and giving it a name as a temporary view, then using that name in an associated query expression.
WITH RECURSIVE
Q1 AS SELECT ... FROM ... WHERE ...,
Q2 AS SELECT ... FROM ... WHERE ...
SELECT ... FROM Q1, Q2, WHERE ... "
Do you know if we can do this in Oracle 9i or 10g. The reason why I am not really fond of "connect by" is that it allows us a very limited control on the recursion specially the type we need for a transitive closure for graphs.
I would be really gratful if you could provide some tips on how to go about solving this problem.
Thanking You,
SumitThanks For the reply..but the problem is not that easy:)... ok Ill try and explain it with an example...Here is a table (P.N. I have just put all the data to be retrieved from a table adjecent ..in real this data will be scattered over a large table..so I can not do select * from...:) )=
nodeID | TagetID | SourceID
1 | a | b
2 | a | c
3 | b | d
4 | b | e
5 | c | f
6 | c | aa
7 | f | ab
8 | f | ac
9 | aa | ad
10 | aa | ae
11 | af | d
12 | af | ba
13 | bb | af
14 | ba | bc
15 | cd | a
16 | ce | a
17 | bf | bd
18 | be | bd
19 | bd | aa
20 | cb | ca
21 | cc | ca
22 | ca | ae
23 | ca | aeWhat I need to do is given a nodeID 10..I will need to retrieve all the above rows from a table...thus the result of my SQL or recursive SQL should give me 23 rows...If you draw the above on paper you will see that the source and the target ids will make a graph.
Any Thoughts?
-Sumit -
Procedure with recursive query working in 11g compiles with error in 10g
Hi, All,
I have a procedure that recursively selects tree-like table (with ID-ParentID relationship). Query itself works perfectly and exactly like I need in 11g and procedure containing it compiles well. But when I try to create the same procedure in 10g then I get a message that procedure compiled with error. I have no other suspicions but on the WITH part of the procedure.
The exact query is here (destination_tariff_zones is the tree-like table which refers to itself by parent_destination_tariff_zone_id):
+ open dtzl_cur FOR
with dtree (nm, iid, alevel, wldcard, dtzindex)
as (select dtz.iname, dtz.iid, 0, dtz.wildcard, rcdi.iindex
from destination_tariff_zones dtz, rating_cube_dimension_indices rcdi, rating_cube_dimensions rcd
where dtz.parent_tariff_zone_id is null and
dtz."rc_dimension_index_id" = rcdi.iid and
rcdi."rc_dimension_id" = rcd.iid and
rcd.rating_cube_id = rc_id and
rcd.dimension_type_id = dim_type
union all
select dtz.iname, dtz.iid, dtree.alevel + 1,
cast ((dtree.wldcard || dtz.wildcard) as varchar2(20)), rcdi.iindex
from dtree, destination_tariff_zones dtz, rating_cube_dimension_indices rcdi, rating_cube_dimensions rcd
where dtree.iid = dtz.parent_tariff_zone_id and
dtz."rc_dimension_index_id" = rcdi.iid and
rcdi."rc_dimension_id" = rcd.iid and
rcd.rating_cube_id = rc_id and
rcd.dimension_type_id = dim_type)
select iid, nm, wldcard, dtzindex
from dtree
order by wldcard;+
Is there any difference between how 11g and 10g handle WITH statements?
Please advise.
Thank you very much in advance,
MaxMax Afanasiev wrote:
then is there any alternative to implement what I need?You can look at using CONNECT BY to emulate a recursive query. If you can post the following we may be able to help:
1. Sample data in the form of CREATE / INSERT statements.
2. Expected output
3. Explanation of expected output (A.K.A. "business logic")
4. Use \ tags for #2 and #3. See FAQ (Link on top right side) for details. -
Need some help with a bottom up recursive query
I need to query some hierarchical data. I've written a recursive query that allows me to examine a parent and all it's related children using an adjacency data model. The scenario is to allow users to track how columns are populated in an ETL process. I've
set up the sample data so that there are two paths:
1. col1 -> col2 -> col3 -> col6
2. col4 - > col5
You can input a column name and get everything from that point downstream. The problem is, you need to be able to start at the bottom and work your way up. Basically, you should be able to put in col6 and see how the data got from col1 to col6. I'm not sure
if it's a matter of rewriting the query or changing the schema to invert the relationships. Any input is welcome. Sample code below.
DECLARE @table_loads TABLE (column_id INT, parent_id INT, table_name VARCHAR(25), column_name VARCHAR(25))
DECLARE @column_name VARCHAR(10)
INSERT INTO @table_loads(column_id, parent_id, table_name, column_name)
SELECT 1,NULL,'table1','col1'
UNION ALL
SELECT 2,1,'table2','col2'
UNION ALL
SELECT 3,2,'table3','col3'
UNION ALL
SELECT 4,NULL,'table4','col4'
UNION ALL
SELECT 5,4,'table5','col5'
UNION ALL
SELECT 6,3,'table6','col6'
SELECT * FROM @table_loads
SET @column_name = 'col1'
WITH load_order(column_id, parent_id,table_name, column_name)
AS(
SELECT column_id, parent_id,table_name, column_name
FROM @table_loads
WHERE column_name = @column_name
UNION ALL
SELECT tl.column_id, tl.parent_id, tl.table_name, tl.column_name
FROM load_order lo
JOIN @table_loads tl
ON lo.column_id = tl.parent_id
SELECT * FROM load_orderGot it. It required a VERY subtle change in the join code:
WITH load_order(column_id, parent_id,table_name, column_name)
AS(
SELECT column_id, parent_id,table_name, column_name
FROM @table_loads
WHERE column_name = @column_name
UNION ALL
SELECT tl.column_id, tl.parent_id, tl.table_name, tl.column_name
FROM @table_loads tl
JOIN load_order lo
ON lo.parent_id = tl.column_id
SELECT * FROM load_order -
Can someone help me in the approach required for optimising a recursive query?Do I create views or do I need to index the tables....what kind of approach do I need to take?
You can try setting cursor_sharing=similar if it is intact
with regards
kccrga -
Using "with as select" to do a recursive query
Hello dear all
I have a question about "with as select" structure.
Is it possible to do a recursive query with this structure?
for example for this table ( river: name,river,lake,sea) i wrote this query to get all of the rivers flowing directly or indirectly in a specific river:
select name from RIVER r
start with r.river='Zaire'
connect by prior r.name=r.river
order by level
now how i can write the same function with "with as select"?
im using oracle 11g.
if you need ,i'll provide create/insert for the table.
best,davidset linesize 132
column Name format a20
column River format a20
column Lake format a20
column Sea format a20
WITH StartWith(
Name,
River,
Lake,
Sea,
Length,
LevelNum
) AS (
SELECT Name,
River,
Lake,
Sea,
Length,
1 LevelNum
FROM RIVER
WHERE River IS NULL
UNION ALL
SELECT r.Name,
r.River,
r.Lake,
r.Sea,
r.Length,
s.LevelNum + 1 LevelNum
FROM RIVER r
INNER JOIN
StartWith s
ON s.Name = r.River
SEARCH DEPTH FIRST BY Name SET NameOrder
SELECT lpad(' ',LevelNum - 1) || Name Name,
River,
Lake,
Sea,
Length
FROM StartWith
ORDER BY NameOrder
NAME RIVER LAKE SEA LENGTH
Amazonas Atlantic Ocean 6518
Amudarja Ozero Aral 1415
Pjandsh Amudarja 1125
Amur Arctic Ocean 2918
Argun Amur 1620
Schilka Amur 560
Ingoda Schilka 708
Onon Schilka 1032
Chatanga Arctic Ocean 1636
Colorado Pacific Ocean 2700
Columbia River Pacific Ocean 1952
NAME RIVER LAKE SEA LENGTH
Connecticut River Atlantic Ocean 660
Cuanza Atlantic Ocean
Cunene Atlantic Ocean
Dalaelv Baltic Sea 520
Oesterdalaelv Dalaelv
Vaesterdalaelv Dalaelv
Djuba Indian Ocean
Dnepr Black Sea 2201
Don Sea of Azov 1870
Donau Black Sea 2850
Drin Mediterranean Sea
NAME RIVER LAKE SEA LENGTH
Black Drin Drin 133
White Drin Drin
Elbe North Sea 1144
Moldau Elbe 435
Gambia Atlantic Ocean
Garonne Atlantic Ocean 650
Gloma North Sea 598
Goetaaelv North Sea 93
Han Yellow Sea
Hudson River Atlantic Ocean 493
Hwangho Yellow Sea
NAME RIVER LAKE SEA LENGTH
Jangtse-Kiang East China Sea 6100
Jenissej Arctic Ocean 4130
Grosser Jenissej Jenissej 605
Kleiner Jenissej Jenissej 680
Joekulsa a Fjoellum Norwegian Sea 206
Karun Persian Gulf 890
Kemijoki Baltic Sea 520
Ounasjoki Kemijoki
Kitakami Pacific Ocean
Klaraelv Vaenern 347
Kokemaeenjoki Baltic Sea 169
NAME RIVER LAKE SEA LENGTH
Kolyma Arctic Ocean 2513
Kura Caspian Sea 1364
Lena Arctic Ocean 4400
Limpopo Indian Ocean
Loire Atlantic Ocean 1010
Mekong South China Sea 4500
Mississippi Gulf of Mexico 3750
Arkansas Mississippi 2334
Missouri Mississippi 3726
Neva Baltic Sea 74
Niger Atlantic Ocean
NAME RIVER LAKE SEA LENGTH
Bani Niger
Benue Niger
Nile Mediterranean Sea
Atbara Nile
Blue Nile Nile
White Nile Nile
Bahr el-Djebel White Nile
Bahr el-Gasal White Nile
Sobat White Nile
Baro Sobat
Pibor Sobat
NAME RIVER LAKE SEA LENGTH
Northern Dwina Arctic Ocean 740
Jug Northern Dwina 574
Suchona Northern Dwina 562
Ob Arctic Ocean 3680
Bija Ob 688
Irtysch Ob 4248
Black Irtysch Irtysch 672
Ischim Irtysch 2450
Katun Ob 306
Tobol Ob 1591
Oranje Atlantic Ocean
NAME RIVER LAKE SEA LENGTH
Vaal Oranje
Orinoco Atlantic Ocean 2736
Oulujoki Baltic Sea
Petschora Arctic Ocean 1809
Rhein Bodensee North Sea 1320
Rhone Mediterranean Sea 812
Rio Balsas Atlantic Ocean 770
Rio Grande Gulf of Mexico 3030
Rio de la Plata Atlantic Ocean 300
Parana Rio de la Plata 4700
Paraguay Parana 2200
NAME RIVER LAKE SEA LENGTH
Uruguay Rio de la Plata 1650
Rufiji Indian Ocean
Ruvuma Indian Ocean
Sanaga Atlantic Ocean
Save Indian Ocean
Schari Tschadsee
Seine North Sea 776
Senegal Atlantic Ocean
St. Lorenzstrom Atlantic Ocean 1170
Syrdarja Ozero Aral 2212
Tana Indian Ocean
NAME RIVER LAKE SEA LENGTH
Thames North Sea 346
Thjorsa Atlantic Ocean 230
Torneaelv Baltic Sea 375
Umeaelv Baltic Sea
Ural Caspian Sea 2428
Volga Caspian Sea 3531
Oka Volga 1480
Volta Atlantic Ocean
Webi Schebeli Indian Ocean
Weichsel Baltic Sea 1068
Weser North Sea 477
NAME RIVER LAKE SEA LENGTH
Fulda Weser 218
Werra Weser 292
Western Dwina Baltic Sea 1020
Zaire Atlantic Ocean 4320
Kwa Zaire 100
Casai Kwa 1570
Cuango Kwa 1230
Cuilo Kwa 970
Lomami Zaire 1600
Lukuga Zaire 230
Luvua Zaire 210
NAME RIVER LAKE SEA LENGTH
Ruki Zaire 730
Busira Ruki 830
Tshuapa Busira 1300
Sanga Zaire 530
Ubangi Zaire 2300
Bomu Ubangi 280
Uelle Ubangi 560
Zambezi Indian Ocean
Chire Zambezi
Kafue Zambezi
Luangwa Zambezi
132 rows selected.
SQL>SY. -
Please help - Recursive Query Restrictions
Hi All,
I wanted to know what restrictions are placed on Oracle Recursive Query capability. Any help or links in this regards would be highly appreciated. Waiting to hear from you.
Thanks,
SnehalCan't think of anything I would term a restriction off the top of my head. There are a few notes in the SQL Reference about precedence that probably aren't obvious.
Are you having a particular problem with this syntax?
Justin
Distributed Database Consulting, Inc.
http://www.ddbcinc.com/askDDBC -
Testing an ISA Server Rule, the recursive query to other DNS Servers test fails
Hello,
I am trying to configure the following infrastructure with ISA Server 2006 and two W2003 servers (called "Server1" and "Server2") . "Server1" is a domain controller, and in
"Server2" is the ISA Server installed, which also has
attached two network Ethernet cards, one called "Internal Ethernet Card", and the other one called
"External Ethernet Card".
The infrastructure would be: "Internal Ethernet Card"---- ISA Server ----"External Ethernet Card"---"Router"----"Internet"
"Internal Ethernet Card" manages the internal package traffic of the infrastructure, the network segment which belongs is isolated from what we could called the Outbound traffic, which is linked to a router. "Internal Ethernet Card" it`s
a virtual network.
"Internal Ethernet Card" feature configuration is the following:
- IP address: 192.168.3.3
- Subnet Mask: 255.255.255.0
- DHCP Enabled: No
- DNS Server: 192.168.3.1 (Must point to the DC "Server1" which has the DNS Service installed)
- Default Gateway: None (because doesnt point to outside)
- Primary WINS Server: 192.168.3.1
The "External Ethernet Card" provides, the outbound connection, and this card is connected to the physical router.
It`s feature configuration is the following:
- IP address: 192.168.1.50
- Subnet Mask: 255.255.255.0
- DHCP Enabled: No
- Default Gateway: 192.168.1.1
- DNS Servers: 192.168.3.1 (Must point to the DC "Server1" which has the DNS Service installed)
After configuring the network cards, I create the following rule in the ISA Server to allow the traffic towards outside from the server and the clients which have joined to the domain:
Action: Allow. Protocol: DNS. From:"Server2". To : External. Condition: All Users
After applying the changes to update the configuration, I enter in the Dns Server of "Server1" and in the "Monitoring" tab, I run a "recursive query to other DNS Servers" but fails.
Only works the "simple query against this DNS Server".
I don`t know why fails, but I`m stucked on this issue, because in the "Server1" DNS Server, in the "domain forward IP address list", I have added two DNS addresses which work OK.
I would appreciate some help to solve this issue.
Thanks
RegardsHello Ms. Long,
Yes, you are right. In the Server1 is configured the DNS server, to use forwarders whose are set in the field "Selected domain`s forwarder IP address list", two DNS address numbers obtained from "Open DNS", which work well.
There is no DNS Server linked to the External NIC.
The Server1 belongs to a private network configured as "VMnet3", which it is set as follows:
IP address: 192.168.3.1
Subnet Mask: 255.255.255.0
Default Gateway: 192.168.3.3
DNS Server: 192.168.3.1
I have tried to test your suggested idea:
> set d2
> google.com
Server: srv-dcfs-01.dominio.local
Address: 192.168.3.1
SendRequest(), len 42
HEADER:
opcode = QUERY, id = 2, rcode = NOERROR
header flags: query, want recursion
questions = 1, answers = 0, authority records = 0, additional = 0
QUESTIONS:
google.com.dominio.local, type = A, class = IN
Got answer (113 bytes):
HEADER:
opcode = QUERY, id = 2, rcode = NXDOMAIN
header flags: response, auth. answer, want recursion, recursion avail.
questions = 1, answers = 0, authority records = 1, additional = 0
QUESTIONS:
google.com.dominio.local, type = A, class = IN
AUTHORITY RECORDS:
-> dominio.local
type = SOA, class = IN, dlen = 46
ttl = 3600 (1 hour)
primary name server = srv-dcfs-01.dominio.local
responsible mail addr = hostmaster
serial = 41
refresh = 900 (15 mins)
retry = 600 (10 mins)
expire = 86400 (1 day)
default TTL = 3600 (1 hour)
SendRequest(), len 28
HEADER:
opcode = QUERY, id = 3, rcode = NOERROR
header flags: query, want recursion
questions = 1, answers = 0, authority records = 0, additional = 0
QUESTIONS:
google.com, type = A, class = IN
DNS request timed out.
timeout was 2 seconds.
timeout (2 secs)
SendRequest failed
*** Request to srv-dcfs-01.dominio.local timed-out
As you can see highlighted in bold, the problem remains in the "recursive query to other DNS Servers" check.
Maybe is better to put the issue on the "Windows Server General Forum" , because the issue has not nothing in common with the ISA Server, dont you?
Thanks
Best regards -
Recursive query to calculate new value in a table.
Hello folks,
I have following data.
drop table transactions;
create table transactions
( ac varchar2(10), rec_seq int, tr_ref int, action varchar2(100), qty int );
select * from transactions;
insert into transactions values ('A1', 1, null, 'BUY', 1);
insert into transactions values ('A1', 2, null, 'BUY', 4);
insert into transactions values ('A1', 3, 1, 'TR to A2', -2);
insert into transactions values ('A1', 4, null, 'SELL', -1);
insert into transactions values ('A1', 5, 2, 'TR from A2', 2);
insert into transactions values ('A1', 6, null, 'BUY', 5);
insert into transactions values ('A1', 3, 3, 'TR to A3', -1);
insert into transactions values ('A2', 1, null, 'BUY', 5);
insert into transactions values ('A2', 2, null, 'BUY', 5);
insert into transactions values ('A2', 3, null, 'BUY', 5);
insert into transactions values ('A2', 4, 1, 'TR from A1', 2);
insert into transactions values ('A2', 5, null, 'SELL', 2);
insert into transactions values ('A2', 6, null, 'BUY', 1);
insert into transactions values ('A2', 7, null, 'BUY', 1);
insert into transactions values ('A2', 8, 2, 'TR to A1', -2);
insert into transactions values ('A2', 9, null, 'sell', 3);
insert into transactions values ('A2', 10, 4, 'TR from A3', 3);
insert into transactions values ('A3', 1, null, 'BUY', 5);
insert into transactions values ('A3', 2, 3, 'TR from A1', 1);
insert into transactions values ('A3', 3, null, 'SELL', 2);
insert into transactions values ('A3', 4, 4, 'TR to A2', -3);I the transactions table that holds the activity took place in a time. Below is some description of the table.
1. rec_seq is the unique for each row within each AC value
2. action column holds the nature of the activity
3. tr_ref holds to link between the transfers. That is, source and destination of the transfers can be matched using this column.
Now I want to write a query such that It returns the whole table with value of rec_seq changed in a recursive fashion that is
1. Compare transfer records using tr_ref.
2. Assign the greatest rec_seq to both the records.
3. Recalculate the rec_seq of the following records from the new value. This recalculation to happen in a recursive fashion.
Any hint/partial or full assistance in this will immensely help.
Thank you.
GirishHi,
Transfers are the key events in this problem. Every time there is a transfer, the new rec_seq number has to be adjusted. The new rec_seq value will be the greater of two numbers:
(1) the req_seq of the last transfer in this ac, plus the number of other transactions in this ac since then, and
(2) the req_seq of the last transfer in the other ac, plus the number of other transactions in that ac since then.
(I assume a transfer always involves two different ac's. If not, the query below can be changed.)
One way to approach this problem is to think of a directed graph, where every node is a transfer row, and it may have up to two parents:
(1) the previous transfer in the same ac
(2) the previous transfer in the other ac
The query below constructs such a graph, then finds all the paths through that graph (in the sub-query named graph). It finds the longest path to each node (weighted by the number of rows between transactions). The main query references that number, and assigns consectuive new_rec_seqs starting with it.
WITH got_trs AS
SELECT ac, rec_seq, tr_ref, action, qTy
, LAST_VALUE (tr_ref IGNORE NULLS) OVER ( PARTITION BY ac
ORDER BY rec_seq
ROWS BETWEEN UNBOUNDED PRECEDING
AND 1 PRECEDING
) AS prev_tr
, LAST_VALUE (tr_ref IGNORE NULLS) OVER ( PARTITION BY ac
ORDER BY rec_seq DESC
) AS next_tr
FROM transactions
-- WHERE ... -- if you need any filtering, put it here
, got_tr_cnt AS
SELECT got_trs.*
, COUNT (*) OVER ( PARTITION BY ac
, next_tr
) AS tr_cnt
FROM got_trs
, nodes AS
SELECT ac
, tr_ref
, tr_cnt
, ac AS parent_ac
, prev_tr AS parent_tr
FROM got_tr_cnt
WHERE tr_ref IS NOT NULL
UNION
SELECT s.ac
, s.tr_ref
, o.tr_cnt
, o.ac AS parent_ac
, o.prev_tr AS parent_tr
FROM got_tr_cnt s
JOIN got_tr_cnt o ON s.tr_ref = o.tr_ref
AND s.ac != o.ac
WHERE o.prev_tr IS NOT NULL
, graph AS
SELECT tr_ref
, MAX ( LENGTH ( REPLACE ( SYS_CONNECT_BY_PATH ( LPAD ('.', tr_cnt, '.')
) AS start_pt
FROM nodes
START WITH parent_tr IS NULL
CONNECT BY parent_tr = PRIOR tr_ref
AND parent_ac = PRIOR ac
GROUP BY tr_ref
SELECT t.ac
, t.rec_seq
, t.tr_ref
, t.action
, t.qty
, NVL ( g.start_pt
, 1
) + ROW_NUMBER () OVER ( PARTITION BY ac
, NVL ( t.tr_ref
, t.prev_tr
ORDER BY rec_seq
- 1 AS new_rec_seq
FROM got_trs t
LEFT OUTER JOIN graph g ON g.tr_ref = NVL ( t.tr_ref
, t.prev_tr
ORDER BY t.ac
, t.rec_seq
;Output:
AC REC_SEQ TR_REF ACTION QTY NEW_REC_SEQ
A1 1 BUY 1 1
A1 2 BUY 4 2
A1 3 1 TR to A2 -2 4
A1 4 SELL -1 5
A1 5 2 TR from A2 2 8
A1 6 BUY 5 9
A1 7 3 TR to A3 -1 10
A2 1 BUY 5 1
A2 2 BUY 5 2
A2 3 BUY 5 3
A2 4 1 TR from A1 2 4
A2 5 SELL 2 5
A2 6 BUY 1 6
A2 7 BUY 1 7
A2 8 2 TR to A1 -2 8
A2 9 sell 3 9
A2 10 4 TR from A3 3 12
A3 1 BUY 5 1
A3 2 3 TR from A1 1 10
A3 3 SELL 2 11
A3 4 4 TR to A2 -3 12I don't recommend trying to store this number in the table; it will be a nightmare trying to keep it up to date. However, if you do want to store it in the table, you can use something like the query above in a MERGE statement.
When trying to understnad any quiery that uses sub-queries, it can be helpful to run the individual sub-queries by themselves, and study the output. -
Recursive Query - Bills of Materials
I have a table that list all Parts that have materials (PartMtl table). Ex. part 1 has materials 2a, 2b, & 2c. I tie this table to a PartCost table linked on the materials. So I get costs for 2a, 2b, & 2c. This works smooth. Now when I want to go a level deeper, and get 2a's materials, 3a, & 3b. things get a little more complicated. Up until this point, I have simply created aliases for the PartMtl & PartCost tables.
The problem with this method is I need to build the report with an alias for each table for each level for as many levels as I imagine our materials listings can grow. This design is shaky at best and does not allow for additional levels. Is there a way to dynamically create this recursion?
Thank you,You can base the report on an SQL Command something like (MS SQL):
declare @level int;
declare @reccnt int;
declare @reccnt2 int;
set @level = 1;
select @level as level,
pm.parent,
pm.component,
pm.qty_required,
pc.cost
into #temp
from PartMtl pm, PartCost pc
where pm.parent = '{?item to explode}'
and pm.component = pc.part_id;
set @reccnt = 0;
set @reccnt2 = ( select count(*) from #temp );
/* loop until no more records inserted */
while @reccnt <> @reccnt2
begin
set @level = @level + 1;
insert into #temp
select @level as level,
pm.parent,
pm.component,
pm.qty_required,
pc.cost
from #temp t, PartMtl pm, PartCost pc
where t.level = @level - 1
and t.component = pm.parent
and pm.component = pc.part_id
set @reccnt = @reccnt2;
set @reccnt2 = ( select count(*) from #temp );
end;
HTH,
Carl -
How to make recursive query in oracle
Dear Experts:
I have "Employees" table and "Departments" Table
The structure of Dept Table is:
ID primary key
parent_dept foreign key(id)
deptname varchar2
deptType varchar2
The Employee table structure is
ID primary key
dept_id foreign key(Department.id)
empName varchar2Sample data for departments
ID : 1
parent_dept : null
deptname: General Manager office
deptType : 'GM'
ID :=2
parent_dept : 1
deptname: Information tech.
deptType : 'DPT'
ID :=3
parent_dept : 2
deptname: Software Development
deptType : 'SECTION'Sample Data for employees
ID : 101
dept_id :1
empName King
ID : 102
dept_id :2
empName ALAN
ID : 103
dept_id :2
empName SAM
ID : 104
dept_id :3
empName JANEI want to create a query that accepts a parameter "p_department_id" and returns All employees on the following conditions
1- In case the parameter value is null , then retrieve All Employees "king - alan- sam-jane"
2- In Case the parameter value is 1 , then retrieve all the employees under department id =1 in addition to all the employees located under the children departments.
in this case it will be "king - alan- sam-jane"
3- In case parameter value is 2 , then return all the employees under department id =2 in addition to all the employees located under the children departments.
In this case it will be " alan- sam-jane"
4- In case parameter value is 3 , then return all the employees under department id =3 in addition to all the employees located under the children departments.
in this case it will be only "JANE"
In brief , If I pass any value to the parameter :p_department_id , I want to retrieve all employees located in this department in addition to other employees located in the child's nodes of this department id
Please help me
ThanksThis is the forum for SQL Developer, not for general SQL or PL/SQL questions.
Please repost this in the SQL and PL/SQL forum. -
How to make recursive query.Please help
Dear Experts:
I want to retrieve all employees located in a department in addition to all other employees located in the child's nodes of this department too.
Problem Details:
I have "Employees" table and "Departments" Table
The structure of Dept Table is:
ID primary key
parent_dept foreign key(id)
deptname varchar2
deptType varchar2
The Employee table structure is
ID primary key
dept_id foreign key(Department.id)
empName varchar2Sample data for departments
ID : 1
parent_dept : null
deptname: General Manager office
deptType : 'GM'
ID :=2
parent_dept : 1
deptname: Information tech.
deptType : 'DPT'
ID :=3
parent_dept : 2
deptname: Software Development
deptType : 'SECTION'Sample Data for employees
ID : 101
dept_id :1
empName King
ID : 102
dept_id :2
empName ALAN
ID : 103
dept_id :2
empName SAM
ID : 104
dept_id :3
empName JANEI want to create a query that accepts a parameter "p_department_id" and returns All employees on the following conditions
1- In case the parameter value is null , then retrieve All Employees "king - alan- sam-jane"
2- In Case the parameter value is 1 , then retrieve all the employees under department id =1 in addition to all the employees located under the children departments.
in this case it will be "king - alan- sam-jane"
3- In case parameter value is 2 , then return all the employees under department id =2 in addition to all the employees located under the children departments.
In this case it will be " alan- sam-jane"
4- In case parameter value is 3 , then return all the employees under department id =3 in addition to all the employees located under the children departments.
in this case it will be only "JANE"
In brief , If I pass any value to the parameter :p_department_id , I want to retrieve all employees located in this department in addition to other employees located in the child's nodes of this department id
I use oracle database 11g release 2
Please help me
Thanks
Edited by: ta**** on Apr 3, 2013 5:56 PM
Edited by: ta**** on Apr 3, 2013 5:58 PMSQL> variable p_department_id number
SQL> exec :p_department_id := null
PL/SQL procedure successfully completed.
SQL> with employees as (
2 select 101 id,1 dept_id,'King' empName from dual union all
3 select 102,2,'ALAN' from dual union all
4 select 103,2,'SAM' from dual union all
5 select 104,3,'JANE' from dual
6 ),
7 departments as (
8 select 1 id,null parent_dept,'General Manager office' deptname,'GM' deptType from dual union all
9 select 2,1,'Information tech.','DPT' from dual union all
10 select 3,2,'Software Development','SECTION' from dual
11 )
12 select *
13 from employees
14 where dept_id in (
15 select id
16 from departments
17 start with (
18 (
19 :p_department_id is null
20 and
21 parent_dept is null
22 )
23 or
24 id = :p_department_id
25 )
26 connect by parent_dept = prior id
27 )
28 /
ID DEPT_ID EMPN
101 1 King
102 2 ALAN
103 2 SAM
104 3 JANE
SQL> exec :p_department_id := 1
PL/SQL procedure successfully completed.
SQL> /
ID DEPT_ID EMPN
101 1 King
102 2 ALAN
103 2 SAM
104 3 JANE
SQL> exec :p_department_id := 2
PL/SQL procedure successfully completed.
SQL> /
ID DEPT_ID EMPN
102 2 ALAN
103 2 SAM
104 3 JANE
SQL> exec :p_department_id := 3
PL/SQL procedure successfully completed.
SQL> /
ID DEPT_ID EMPN
104 3 JANE
SQL> SY. -
Hi ,
I need help very urgently.
i have a parent child relation like this
parent child
0 133
133 134
133 135
134 140
135 146
146 150
150 155
155 160
i pass the parent ie 133 to an algo and i want its deepest child ie 160.
pls reply with the algorithm for doing this.Using a recursive table expression is supported in many database systems the following example uses a table created to hold your data with "p" as the parent column and "c" as the child column:
WITH LPC (Lev, p, c) AS
SELECT 1, ROOT.p, ROOT.c
FROM test2 ROOT
WHERE ROOT.c = 146
UNION ALL
SELECT PARENT.Lev+1, CHILD.p, CHILD.c
FROM LPC PARENT, test2 CHILD
WHERE PARENT.c = CHILD.p
SELECT Lev, p, c
FROM LPC
order by 1 desc
The 146 above would be parameterized and only the first row of the result set would be used if you didn't want the whole hierarchy dump. -
How to do recursive query?
I have a table:
ID /PARENTID/ CATEGORY
1 /****/ ROOT 1
2 /****/ ROOT 3
3 / 2/ ROOT 3.1
4 / 1/ ROOT 1.1
5 / 4/ ROOT 1.1.1
6 / 5/ ROOR 1.1.1.1
7 / 3/ ROOT 3.1.1
**** means column is blank, meaning that ID has no ParentID because it is already the topmost parent id.
I just used "/" to separate the different column values.
I will be given an ID as an input to my stored proc then im going to find the topmost parent id for that given id. Afterwhich, when i already got hold of the topmost parent id. I need to query it in another table to see if this parent id satisfies a certain condition of my program. Then if it satisifes, i will return true as a return value of my stored proc. I know how to query to test for the certain condition of the program. Wha I need is the loop structure and the select statement. what kind of loop that i will use? while? for loop?Suggest you look at CONNECT BY syntax in documentation.
Oracle9i Enterprise Edition Release 9.2.0.6.0 - 64bit Production
JServer Release 9.2.0.6.0 - Production
SQL> SELECT MAX (id) KEEP (
2 DENSE_RANK LAST
3 ORDER BY LEVEL) id
4 FROM table_name
5 START WITH id = 7
6 CONNECT BY PRIOR parentid = id;
ID
2
SQL>
Oracle Database 10g Enterprise Edition Release 10.1.0.3.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
SQL> SELECT id
2 FROM table_name
3 WHERE CONNECT_BY_ISLEAF = 1
4 START WITH id = 7
5 CONNECT BY PRIOR parentid = id;
ID
2
SQL> -
Hi All,
I have below table
IT_Terms_First_Date
IT_Terms_Last_Date
DI_Debt_Num
IT_Terms_Seq_Num
200501
201101
1000
131
200512
203412
1001
131
200503
204209
1003
131
200507
201001
1004
131
200510
202710
1005
131
200506
202412
10020
131
197910
198310
257000
101
198009
202909
298000
101
198101
202908
298000
103
198105
202910
298000
104
199109
201309
578000
101
199204
201110
600000
101
198009
201010
298010
101
198105
204010
298010
104
201011
202909
298010
103
I need to check whether my DI_Debt_Num having Ovelaping or not for each DI_Debt_Num,
at this moment we are checking each row in loop and usnig function
exec @Overlap1=[DffMonths] @ITtermsLD,@ITtermsNextFD
exec @Overlap2=[DffMonths] @ITtermsFD,@ITtermsNextFD
exec @Overlap3=[DffMonths] @ITtermsFD,@ITtermsNextLD
if(@Overlap1>0 and (@Overlap2<=0 OR @Overlap3<0))
BEGIN
SET @CheckOverlap=1
END
here @ITtermsLD is the IT_Terms_Last_Date of the current DI_Debt_Num,@ITtermsNextFD is the IT_Terms_First_Date of the next row. @ITtermsFD is the IT_Terms_First_Date of the current month
if we consider the 298000 DI_Debt_Num we have 3 IT_Terms_Seq_Num 101,103,104
in this senario we need to check only the first 2 rows from that itself we can identify it is overlapped ,but when we consider the 298010 we need to check all 3 IT_Terms_Seq_Num 101,103,104 if we consider first two rows 101 & 103 it is not overlapped.Then
we have to check first row with 3rd row ie 104 and it is overlapped.We are checking the overlap senario for DI_Debt_Num having multipple IT_Terms_Seq_Num rows
Some situation first row may not be overlapped with other rows .Then we have to check the 2nd row with the next rows in the same way we are doing for first row
My aim is to covert this looping method to a select query to improve my query performance
Thanks in advance
RoshanPlease post DDL, so that people do not have to guess what the keys, constraints, Declarative Referential Integrity, data types, etc. in your schema are. Learn how to follow ISO-11179 data element naming conventions and formatting rules. You have no idea,
do you? Temporal data should use ISO-8601 formats. You failed again! I will guess that your dates are months. Code should be in Standard SQL as much as possible and not local dialect.
This is minimal polite behavior on SQL forums.
>> I have below table <<
This is not a table! Where is the DDL? This picture has no name. Not even a name!! There is no “seq_nbr” in RDBMS; it has to be a “<something in particular>_seq” and there are no duplicates in a sequence.
My guess is that each di_debt_nbr has a sequence within its range. I will call it the “foobar_seq” for lack of a name.
My next guess is that your dates are really months and you do not know about using a report period table. This idiom gives a name to a range of dates that is common to the entire enterprise.
CREATE TABLE Something_Report_Periods
(something_report_name CHAR(10) NOT NULL PRIMARY KEY
CHECK (something_report_name LIKE <pattern>),
something_report_start_date DATE NOT NULL,
something_report_end_date DATE NOT NULL,
CONSTRAINT date_ordering
CHECK (something_report_start_date <= something_report_end_date),
etc);
These report periods can overlap or have gaps. I like the MySQL convention of using double zeroes for months and years, That is 'yyyy-mm-00' for a month within a year and 'yyyy-00-00' for the whole year. The advantages are that it will sort with the ISO-8601
data format required by Standard SQL and it is language independent. The pattern for validation is '[12][0-9][0-9][0-9]-00-00' and '[12][0-9][0-9][0-9]-[01][0-9]-00'
Here is another guess at what you want, if you knew what a table is:
CREATE TABLE DI_Debts
(it_terms_first_date CHAR(10) NOT NULL
REFERENCES Report_Period (month_name),
it_terms_last_date CHAR(10) NOT NULL
REFERENCES Report_Period (month_name),
CHECK (it_terms_first_date <= it_terms_last_date),
di_debt_nbr INTEGER NOT NULL,
foobar_seq INTEGER NOT NULL,
PRIMARY KEY (di_debt_nbr, foobar_seq));
INSERT INTO DI_Debts
VALUES
('2005-01-00', '2011-01-00', 1000, 1),
('2005-12-00', '2034-12-00', 1001, 1),
('2005-03-00', '2042-09-00', 1003, 1),
('2005-07-00', '2010-01-00', 1004, 1),
('2005-10-00', '2027-10-00', 1005, 1),
('2005-06-00', '2024-12-00', 100201, 1),
('1979-10-00', '1983-10-00', 257000, 1),
('1980-09-00', '2029-09-00', 2980001, 1),
('1981-01-00', '2029-08-00', 298000, 1),
('1981-05-00', '2029-10-00', 298000, 2),
('1991-09-00', '2013-09-00', 578000, 1),
('1992-04-00', '2011-10-00', 600000, 1),
('1980-09-00', '2010-10-00', 298010, 1),
('1981-05-00', '2040-10-00', 298010, 2),
('2010-11-00', '2029-09-00', 298010, 3);
I need to check whether my DI_Debt_nbr are overlapping or not for each DI_Debt_nbr,
>> at this moment we are checking each row in loop and using function
exec @Overlap1=[DffMonths] @IttermsLD, @ITtermsNextFD;
exec @Overlap2=[DffMonths] @IttermsFD, @ITtermsNextFD;
exec @Overlap3=[DffMonths] @IttermsFD, @ITtermsNextLD; <<
And you were too rude to post the code for these functions! You write SQL with assembly language flags! We do not do that! We also would use a CASE expression, and not IF-THEN control flow in SQL.
Did you know that ANSI/ISO Standard SQL has a temporal <overlaps predicate>? Notice the code to handle NULLs and the ISO half-open interval model.
(start_date_1 > start_date_2
AND NOT (start_date_1 >= end_date_2
AND end_date_1 >= end_date_2))
OR (start_date_2 > start_date_1
AND NOT (start_date_2 >= end_date_1
AND end_date_2 >= end_date_1))
OR (start_date_1 = start_date_2
AND (end_date_1 <> end_date_2 OR end_date_1 = end_date_2))
I tend to prefer the use of a calendar table. NULLs return an empty set, as above.
EXISTS
((SELECT cal_date FROM Calendar
WHERE cal_date BETWEEN start_date_1 AND end_date_1)
INTERSECT
(SELECT cal_date FROM Calendar
WHERE cal_date BETWEEN start_date_2 AND end_date_2))
--CELKO-- Books in Celko Series for Morgan-Kaufmann Publishing: Analytics and OLAP in SQL / Data and Databases: Concepts in Practice Data / Measurements and Standards in SQL SQL for Smarties / SQL Programming Style / SQL Puzzles and Answers / Thinking
in Sets / Trees and Hierarchies in SQL -
Why does recursive query only organize the first item in the subquery?
Following is my recursive function and it only updates the first two item in my subquery..
select distinct f.DISPLAY_NAME, f.id,f.parent_id, f.sub_folder_sequence
from WWSBR_ALL_FOLDERS f, WWSBR_ALL_FOLDERS g start with f.id in
(select g.parent_id from WWSBR_ALL_FOLDERS e
where
e.id = g.parent_id AND
f.id = g.parent_id AND
e.caid = 103 AND
e.parent_id <> 0 AND
e.type_id = 1 AND
e.display_in_parent_folder <> 0)
connect by prior f.id= f.parent_id
order by f.sub_folder_sequence asc, f.parent_id asc, f.id desc;following is my result
DISPLAY_NAME
ID PARENT_ID SUB_FOLDER_SEQUENCE
Home Page
8981 1 1
Claims
9192 8981 1
Advanced Search
9168 9163 1
DISPLAY_NAME
ID PARENT_ID SUB_FOLDER_SEQUENCE
Sales Chart
9187 9173 1
Search
9163 1 2
Sales
9173 1 3
6 rows selected.
Maybe you are looking for
-
Replacing HD With SSD, Need To Install OS X (Not Clone Old HD) On New SSD
Hello All!! I am getting a new Samsung 830 series 256GB SSD today which I am going to put in my 2011 (late year) MacBook Pro 15". I would like to put the new SSD in with a fresh installation of OS X (I don't want to clone my old hard drive). Can anyo
-
SAP Form layout output in MS word doc.
Hi Everybody, I have a requirement from business where they would like to get the output of a docuemnt in MS word format so that they can add some text or input text in the output and then manually send to customer through mail. Now the question is b
-
Reading Text File from selection Screen and populating table (Urgent)
Hi All, I have some requirment like i in my report i have to initial my Input feild from text file is it good to populate a internal table or range. I have three feild in a excel file that entry can more then 500 data example Matnr Date D
-
When I first got my iMac Intel things were very fast, Safari would load in one bounce, Mail would load in half a bounce. After a few weeks and frankly its no faster than the outgoing single 1.6 powermac, safari frequently has the beachball of death f
-
IO Budget exceeded error message BP603
Dear Gurus, I need to make the Error message to Warning relate Internal Order Budget exceeded. Is there any SAP note suggesting to add Error message BP603 to table T100s. Application area BP is already given in T100SA. But the message BP603 is not