Query on Recursive Table (self-join)?
Hi all,
I have a table with a self join, basically an employee is managed by an employee..
Using the following query, i'm able to query the data, giving a kind of hierarchical output, this tells me who manages who...
SELECT LPAD(' ', 5* level) || empno
FROM employee
CONNECT BY prior empno = mgr
START WITH mgr is null;This produces the following output...
SQL> SELECT LPAD(' ', 5* level) || ep_emp_id
2 FROM employee_on_project
3 CONNECT BY prior ep_emp_id = ep_mgr_emp_id
4 START WITH ep_mgr_emp_id is null;
LPAD('',5*LEVEL)||EP_EMP_ID
c1
c2
c4
c5
c6
c3
c7
7 rows selected.My question is, how can I edit the query to output only employees at the top of the hierarchy, i.e. only top managers.
Any idea's guys??
Cheers!
Depending on what you mean by "top managers", but this seems the obvious solution:
SELECT ep_emp_id
FROM employees_on_project
WHERE ep_mgr_emp_id IS NULLalternatively, if employees_on_project is actually complex view, and not a simple table, then this may be a better alternative:
SELECT emp_id
FROM (SELECT ep_emp_id, level lv
FROM employee_on_project
CONNECT BY prior ep_emp_id = ep_mgr_emp_id
START WITH ep_mgr_emp_id is null)
WHERE lv = 1TTFN
John
Similar Messages
-
Oracle query with out using self join
hi friends,
i have one table for exeample PERSTATUS
pk/fK STUDENT NUMBER SUBJECT MARKS STATUS
1 ACCOUNTS 15 RED
1 MATHS 35 YELLOW
1 SCINECE 45 GREEN
2 ACCOUNTS 55 BROWN
2 MATHS 35 YELLOW
2 SCINECE 45 GREEN
3 ACCOUNTS 15 RED
3 MATHS 35 YELLOW
3 SCINECE 45 GREEN
i want students how status is both red and yellow so i am using self join
i want students status is both red and yellow so i am using self join
SELECT PS.STUDENTNUMBER,PS.STATUS,PS.STATUS1 FROM PERSTATUS PS ,PERSTATUS PS1
WHERE PS.STUDENTNUMBER-PS1.STUDENTNUMER
PS.STATUS='RED' AND PS1.STAUTS='YELLOW'
i want students status is both RD and YELLOW AND GREEN so i am using self join( two self joinS}
SELECT PS.STUDENTNUMBER,PS.STATUS,PS.STATUS,PS2.STATUS FROM PERSTATUS PS ,PERSTATUS PS1,PERSTATUS PS2
WHERE PS.STUDENTNUMBER-PS1.STUDENTNUMER AND PS.STUDENTNUMBER-PS2.STUDENTNUMBER
PS.STATUS='RED' AND PS1.STAUTS='YELLOW' AND PS2.STAUTUS='GREEN'
if i require MORE STATUS then more self joins required, is there any alternative to achive this
and if results comes in multiple rows are accepted (since with the above query result will come in single row)
i tried to use group by (studentnumber,status) with status='red' and status='yellow'
but it is not possible could you povidet he solutionHi,
Whenever you have a problem, please post CREATE TABLE and INSERT statements for your sample data, and the exact results you want from that data. Explain how you get those results from that data.
See the forum FAQ {message:id=9360002}
Here's an example of how to post the sample data:
CREATE TABLE perstatus
( studentnumber NUMBER
, subject VARCHAR2 (10)
, marks NUMBER
, status VARCHAR2 (10)
INSERT INTO perstatus (studentnumber, subject, marks, status)
VALUES (1, 'ACCOUNTS', 15, 'RED');
INSERT INTO perstatus (studentnumber, subject , marks, status)
VALUES (1, 'MATHS', 35, 'YELLOW');
INSERT INTO perstatus (studentnumber, subject, marks, status)
VALUES (1, 'SCINECE', 45, 'GREEN');
INSERT INTO perstatus (studentnumber, subject, marks, status)
VALUES (2, 'ACCOUNTS', 55, 'BROWN');
INSERT INTO perstatus (studentnumber, subject , marks, status)
VALUES (2, 'MATHS', 35, 'YELLOW');
INSERT INTO perstatus (studentnumber, subject, marks, status)
VALUES (2, 'SCINECE', 45, 'GREEN');
INSERT INTO perstatus (studentnumber, subject, marks, status)
VALUES (3, 'ACCOUNTS', 15, 'RED');
INSERT INTO perstatus (studentnumber, subject , marks, status)
VALUES (3, 'MATHS', 35, 'YELLOW');
INSERT INTO perstatus (studentnumber, subject, marks, status)
VALUES (3, 'SCINECE', 45, 'GREEN');You were on the right track, thinking about GROUP BY. You're interested in something about the whole group of rows that has the same studentnumber. Looking at any individual row won't tell you if that row is part of the group you're interested in or not.
If you want to see information about the group as a whole, you can do the whole job with GROUP BY. In this case, studnetnumber is the only thing that an entire group has in common. If you wanted to see the studentnumbers that had both RED and YELLOW, that is:
STUDENTNUMBER
1
3here's one way you could do it:
SELECT studentnumber
FROM perstatus
WHERE status IN ('RED', 'YELLOW')
GROUP BY studentnumber
HAVING COUNT (DISTINCT status) = 2 -- That is, both RED and YELLOW
ORDER BY studentnumber
;But say you wanted to see details about individuals in the group; for example, say we want to see all the columns for students that have all 3 of RED, YELLOW and GREEN, like this:
STUDENTNUMBER SUBJECT MARKS STATUS
1 SCINECE 45 GREEN
1 ACCOUNTS 15 RED
1 MATHS 35 YELLOW
3 SCINECE 45 GREEN
3 ACCOUNTS 15 RED
3 MATHS 35 YELLOWWe used the aggregate COUNT function earlier, but aggregate functions require collapsing the results down to one row per group.
However, most of the aggregate functions, like COUNT, have analytic counterparts, that can give the same results without collapsing the result set. Here's one way to get the results above, using the analytic COUNT function:
WITH got_cnt AS
SELECT studentnumber, subject, marks, status
, COUNT ( DISTINCT CASE
WHEN status IN ('RED', 'YELLOW', 'GREEN')
THEN status
END
) OVER (PARTITION BY studentnumber) AS cnt
FROM perstatus
SELECT studentnumber, subject, marks, status
FROM got_cnt
WHERE cnt = 3
ORDER BY studentnumber
, status
; -
SQL Query, group by or self join?
Hi All,
I have a table with about 100,000 rows.. It is a linking table. I want to filter out some of the data. At the bottom I will put a sample table. I am really after advice if I should be using the group by, or something else. It is really slow, and I really wanted to make a view from the query, but it won't run in realtime (I thought about Materialised views, but the data could change and I would want it updated)
So the data would like like this.
1 1
A 1
B 1
1 A
1 B
2 null/0
And I want to transform it into a result that looks like this.
A 1
B 1
2 0
(I can live with 1 1 as well)
The first query I have come up with is
select
A.TXN, A.ID SCHED_INFO, A.STA ORIG_ACT
from
SELECT
Txn, ID,
STA
FROM TEST_STA
WHERE TXN < 0
) A,
select ID, count(STA)
FROM test_STA
WHERE TXN < 0
group by ID
HAVING count(STA) > 1
) B
where A.ID = B.ID
OR A.STA = '0'
The second I came up with was.
select B.Id , A.id STA
from test_STA A, test_STA B
where A.STA = '0'
AND B.STA != '0'
AND B.STA = A.ID
AND b.TXN < 0
Where the data looks like
create table test_STA
( TXN NUMBER,
ID VARCHAR2(20),
STA VARCHAR2(20) )
insert into test_STA Values (1, '1', '0')
insert into test_STA Values (-1, '1', '1')
insert into test_STA Values (-1, '1', 'A')
insert into test_STA Values (-1, '1', 'B')
insert into test_STA Values (-1, 'A', '1')
insert into test_STA Values (-1, 'B', '1')
insert into test_STA Values (-1, '2', '0')
TXN is the transaction number -1 is current, others (> 0 are old)
What does all this mean..
Well
1 is a parent, with A and B as children.
2 is a parent with no children.
So what I want to do return is Parents with no children, and children but not their parents..
So which path should I continue my efforts down do you think ? The first one, with the group by, or the second one, with the join to it's self.
PaulHi,
If you can guarantee, that every child has also a record then following query returns your result:
select ID, count(*)
from test_STA
group by ID
having count(*) = 1
ID COUNT(*)
2 1
A 1
B 1 -
How to query 2 hierarchical tables and join?
Hi
I've been bashing my head against a well to get this to work efficiently in 10g. I can solve the following writing some pretty horrible SQL, but can't figure out how to do it elegantly and optimally.
We have two hierarchical tables as follows:
select * from data_categories dac
dac_code name parent_dac_code
10 MANAGEMENT
20 MEDICATION 10
30 PROCEDURE 10
40 SURVEY
50 ASSESS
60 NATURE 50
70 OBSERVE 60
select * from data_elements des
des_id name parent_des_id dac_code display_seq
100 DOSE MEDICATION 1
110 1MG 100 1
120 2MG 100 2
130 3MG 100 3
140 ROUTE MEDICATION 2
150 ET 140 1
160 EM 140 2
170 RESPONSE MEDICATION 3
180 IMPROVED 170 1
190 NOCHANGE 170 2
200 FILED MANAGEMENT 1
210 INPUT OBSERVE 1
You'll note:
1) We have hierarchies in both tables, and a fk from data_elements to data_categories via the dac_code.
2) The depth of both data_categories and data_elements is unlimited.
3) There is no single root node record in either table.
4) The appropriate PK and FK indexes exist.
We need to write a query that returns the following results:
root_dac_code parent_dac_code des_level des_id name display_seq
ASSESS OBSERVE 1 210 INPUT 1
MANAGEMENT MEDICATION 1 100 DOSE 1
MANAGEMENT MEDICATION 2 110 1MG 1
MANAGEMENT MEDICATION 2 120 2MG 2
MANAGEMENT MEDICATION 2 130 3MG 3
MANAGEMENT MEDICATION 1 140 ROUTE 1
MANAGEMENT MEDICATION 2 150 ET 1
MANAGEMENT MEDICATION 2 160 EM 2
MANAGEMENT MEDICATION 1 170 RESPONSE 3
MANAGEMENT MEDICATION 2 180 IMPROVED 1
MANAGEMENT MEDICATION 2 190 NOCHANGE 2
MANAGEMENT MANAGEMENT 1 200 FILED 1
You'll also note we need to return the data in order of the root_dac_code, then parent_dac_code, followed by the display_seq.
Does anybody know how to write this query in an elegant and optimal manner?
Many thanks for any help!
Cheers,
CM.Flakey model.
Why does data_elements.dac_code appear to refer to data_categories.name rather than data_categories.dac_code?
You do not appear to be ordering by root_dac_code, parent_dac_code and display_seq (if you were MANAGEMENT/MANAGEMENT would not be at the end). Did you perhaps mean ORDER BY root_dac_code, des_id, display_seq?
Something like this perhaps?
Oracle Database 10g Enterprise Edition Release 10.1.0.2.0 - 64bit Production
With the Partitioning, OLAP and Data Mining options
SQL> CREATE TABLE data_categories (
2 dac_code NUMBER,
3 name VARCHAR2 (30),
4 parent_dac_code NUMBER);
Table created.
SQL> INSERT INTO data_categories VALUES (10, 'MANAGEMENT', NULL);
1 row created.
SQL> INSERT INTO data_categories VALUES (20, 'MEDICATION', 10);
1 row created.
SQL> INSERT INTO data_categories VALUES (30, 'PROCEDURE', 10);
1 row created.
SQL> INSERT INTO data_categories VALUES (40, 'SURVEY', NULL);
1 row created.
SQL> INSERT INTO data_categories VALUES (50, 'ASSESS', NULL);
1 row created.
SQL> INSERT INTO data_categories VALUES (60, 'NATURE', 50);
1 row created.
SQL> INSERT INTO data_categories VALUES (70, 'OBSERVE', 60);
1 row created.
SQL> CREATE TABLE data_elements (
2 des_id NUMBER,
3 name VARCHAR2 (30),
4 parent_des_id NUMBER,
5 dac_code VARCHAR2 (30),
6 display_seq NUMBER);
Table created.
SQL> INSERT INTO data_elements VALUES (100, 'DOSE', NULL, 'MEDICATION', 1);
1 row created.
SQL> INSERT INTO data_elements VALUES (110, '1MG', 100, NULL, 1);
1 row created.
SQL> INSERT INTO data_elements VALUES (120, '2MG', 100, NULL, 2);
1 row created.
SQL> INSERT INTO data_elements VALUES (130, '3MG', 100, NULL, 3);
1 row created.
SQL> INSERT INTO data_elements VALUES (140, 'ROUTE', NULL, 'MEDICATION', 2);
1 row created.
SQL> INSERT INTO data_elements VALUES (150, 'ET', 140, NULL, 1);
1 row created.
SQL> INSERT INTO data_elements VALUES (160, 'EM', 140, NULL, 2);
1 row created.
SQL> INSERT INTO data_elements VALUES (170, 'RESPONSE', NULL, 'MEDICATION', 3);
1 row created.
SQL> INSERT INTO data_elements VALUES (180, 'IMPROVED', 170, NULL, 1);
1 row created.
SQL> INSERT INTO data_elements VALUES (190, 'NOCHANGE', 170, NULL, 2);
1 row created.
SQL> INSERT INTO data_elements VALUES (200, 'FILED', NULL, 'MANAGEMENT', 1);
1 row created.
SQL> INSERT INTO data_elements VALUES (210, 'INPUT', NULL, 'OBSERVE', 1);
1 row created.
SQL> SELECT dc.root_dac_code, de.parent_dac_code,
2 de.des_level, de.des_id, de.name, de.display_seq
3 FROM (SELECT LEVEL des_level, des_id, name, parent_des_id,
4 CONNECT_BY_ROOT (dac_code) parent_dac_code, display_seq
5 FROM data_elements da
6 START WITH parent_des_id IS NULL
7 CONNECT BY PRIOR des_id = parent_des_id) de,
8 (SELECT CONNECT_BY_ROOT (name) root_dac_code, name dac_code
9 FROM data_categories
10 START WITH parent_dac_code IS NULL
11 CONNECT BY PRIOR dac_code = parent_dac_code) dc
12 WHERE de.parent_dac_code = dc.dac_code
13 ORDER BY dc.root_dac_code, de.des_id, de.display_seq;
ROOT_DAC_CODE PARENT_DAC_CODE DES_LEVEL DES_ID NAME
ASSESS OBSERVE 1 210 INPUT
MANAGEMENT MEDICATION 1 100 DOSE
MANAGEMENT MEDICATION 2 110 1MG
MANAGEMENT MEDICATION 2 120 2MG
MANAGEMENT MEDICATION 2 130 3MG
MANAGEMENT MEDICATION 1 140 ROUTE
MANAGEMENT MEDICATION 2 150 ET
MANAGEMENT MEDICATION 2 160 EM
MANAGEMENT MEDICATION 1 170 RESPONSE
MANAGEMENT MEDICATION 2 180 IMPROVED
MANAGEMENT MEDICATION 2 190 NOCHANGE
MANAGEMENT MANAGEMENT 1 200 FILED
12 rows selected.
SQL> -
Hi. I need to query the database of a document management system. Documents are logically stored in folders in a tree structure and may be nested to arbitrary depth. The FOLDER table lists the names and metadata of folders.
Ultimately, I want to join the FOLDER table ("f") to the DOCUMENT table ("d") to get a list of documents by folder. The main thing I need help with is to build folder paths. I don't necessarily even
need to build full paths. I would be happy just listing all the individual folders under the root, and the documents they contain. I imagine to build folder paths involves a self join, but I don't know how to hadle arbitrary depth
The first two columns of the FOLDER table are FOLDER_ID and PARENT_FOLDER_ID. The data looks like this (where FOLDER_ID 1 represents the root folder):
FOLDER_ID PARENT_FOLDER_ID
1 null
2 1
3 1
4 1
5 2
6 2
7 1
etc.
Thanks for your help!See Itzik Ben-Gan examples dealing with such queries.
CREATE TABLE Employees
empid int NOT NULL,
mgrid int NULL,
empname varchar(25) NOT NULL,
salary money NOT NULL,
CONSTRAINT PK_Employees PRIMARY KEY(empid),
CONSTRAINT FK_Employees_mgrid_empid
FOREIGN KEY(mgrid)
REFERENCES Employees(empid)
CREATE INDEX idx_nci_mgrid ON Employees(mgrid)
SET NOCOUNT ON
INSERT INTO Employees VALUES(1 , NULL, 'Nancy' , $10000.00)
INSERT INTO Employees VALUES(2 , 1 , 'Andrew' , $5000.00)
INSERT INTO Employees VALUES(3 , 1 , 'Janet' , $5000.00)
INSERT INTO Employees VALUES(4 , 1 , 'Margaret', $5000.00)
INSERT INTO Employees VALUES(5 , 2 , 'Steven' , $2500.00)
INSERT INTO Employees VALUES(6 , 2 , 'Michael' , $2500.00)
INSERT INTO Employees VALUES(7 , 3 , 'Robert' , $2500.00)
INSERT INTO Employees VALUES(8 , 3 , 'Laura' , $2500.00)
INSERT INTO Employees VALUES(9 , 3 , 'Ann' , $2500.00)
INSERT INTO Employees VALUES(10, 4 , 'Ina' , $2500.00)
INSERT INTO Employees VALUES(11, 7 , 'David' , $2000.00)
INSERT INTO Employees VALUES(12, 7 , 'Ron' , $2000.00)
INSERT INTO Employees VALUES(13, 7 , 'Dan' , $2000.00)
INSERT INTO Employees VALUES(14, 11 , 'James' , $1500.00)
The first request is probably the most common one:
returning an employee (for example, Robert whose empid=7)
and his/her subordinates in all levels.
The following CTE provides a solution to this request:
WITH EmpCTE(empid, empname, mgrid, lvl)
AS
-- Anchor Member (AM)
SELECT empid, empname, mgrid, 0
FROM Employees
WHERE empid = 7
UNION ALL
-- Recursive Member (RM)
SELECT E.empid, E.empname, E.mgrid, M.lvl+1
FROM Employees AS E
JOIN EmpCTE AS M
ON E.mgrid = M.empid
SELECT * FROM EmpCTE
Using this level counter you can limit the number of iterations
in the recursion. For example, the following CTE is used to return
all employees who are two levels below Janet:
WITH EmpCTEJanet(empid, empname, mgrid, lvl)
AS
SELECT empid, empname, mgrid, 0
FROM Employees
WHERE empid = 3
UNION ALL
SELECT E.empid, E.empname, E.mgrid, M.lvl+1
FROM Employees as E
JOIN EmpCTEJanet as M
ON E.mgrid = M.empid
WHERE lvl < 2
SELECT empid, empname
FROM EmpCTEJanet
WHERE lvl = 2
As mentioned earlier, CTEs can refer to
local variables that are defined within the same batch.
For example, to make the query more generic, you can use
variables instead of constants for employee ID and level:
DECLARE @empid AS INT, @lvl AS INT
SET @empid = 3 -- Janet
SET @lvl = 2 -- two levels
WITH EmpCTE(empid, empname, mgrid, lvl)
AS
SELECT empid, empname, mgrid, 0
FROM Employees
WHERE empid = @empid
UNION ALL
SELECT E.empid, E.empname, E.mgrid, M.lvl+1
FROM Employees as E
JOIN EmpCTE as M
ON E.mgrid = M.empid
WHERE lvl < @lvl
SELECT empid, empname
FROM EmpCTE
WHERE lvl = @lvl
Results generated thus far might be returned (but are not guaranteed to be),
and error 530 is generated. You might think of using the MAXRECURSION option
to implement the request to return employees who are two levels below
Janet using the MAXRECURSION hint instead of the filter in the recursive member
WITH EmpCTE(empid, empname, mgrid, lvl)
AS
SELECT empid, empname, mgrid, 0
FROM Employees
WHERE empid = 1
UNION ALL
SELECT E.empid, E.empname, E.mgrid, M.lvl+1
FROM Employees as E
JOIN EmpCTE as M
ON E.mgrid = M.empid
SELECT * FROM EmpCTE
OPTION (MAXRECURSION 2)
WITH EmpCTE(empid, empname, mgrid, lvl, sortcol)
AS
SELECT empid, empname, mgrid, 0,
CAST(empid AS VARBINARY(900))
FROM Employees
WHERE empid = 1
UNION ALL
SELECT E.empid, E.empname, E.mgrid, M.lvl+1,
CAST(sortcol + CAST(E.empid AS BINARY(4)) AS VARBINARY(900))
FROM Employees AS E
JOIN EmpCTE AS M
ON E.mgrid = M.empid
SELECT
REPLICATE(' | ', lvl)
+ '(' + (CAST(empid AS VARCHAR(10))) + ') '
+ empname AS empname
FROM EmpCTE
ORDER BY sortcol
(1) Nancy
| (2) Andrew
| | (5) Steven
| | (6) Michael
| (3) Janet
| | (7) Robert
| | | (11) David
| | | | (14) James
| | | (12) Ron
| | | (13) Dan
| | (8) Laura
| | (9) Ann
| (4) Margaret
| | (10) Ina
Best Regards,Uri Dimant SQL Server MVP,
http://sqlblog.com/blogs/uri_dimant/
MS SQL optimization: MS SQL Development and Optimization
MS SQL Consulting:
Large scale of database and data cleansing
Remote DBA Services:
Improves MS SQL Database Performance
SQL Server Integration Services:
Business Intelligence -
Problem writing a XSLT to convert XML in desired format from a table having self join
Hello,
I have to write a style sheet to convert XML generated from XSQL into a different format. The query that I have is as follows.
select LEVEL depth,
'H' || hierarchy_id id,
name,
nvl2(parent_id, 'H' || parent_id, 0) parent_id,
CURSOR(select LEVEL depth,
'H' || hierarchy_id hid,
name hname,
nvl2(parent_id, 'H' || parent_id, 0) hparent_id,
decode(system_id, NULL, '0', 'S' || system_id) formatted_system_id,
system_id
from hierarchy
where parent_id = h.hierarchy_id
and system_id is not null
) as systems
from hierarchy h
where system_id is null
start with parent_id is null
connect by prior hierarchy_id = parent_id
The hierarchy table has a self join to itself. The selfjoin is on the hierarchyid and the parentid fields which is evident from the query.
Here the hierarchy table contains the parent system and also the child systems underneath. The problem is that the no. of levels that it can go deep is not fixed. The output of this in sqlplus is as follows.
Depth Hierarchyid, name parentid
1 h1 xxx <null>
2 h2 bbb h1
3 h3 ccc h2
<Cursor for systems>
hid hname hparentid formatted_system_id systemid
h4 ccc h2 s1 1
h5 ccc h2 s2 2
<Back to original data>
Depth Hierarchyid, name parentid
2 h6 ddd h1
2 h7 eee h1
The desired output required from the stylesheet is as follows
<h id=h1 name=xxx>
<h id=h2 name=bbb parentid=h1>
<h id=h3 name=ccc parentid=h2>
<h id=h4 name=fff parentid=h3 systemid=s1>
<h id=h5 name=ggg parentid=h3 systemid=s2>
</h>
</h>
<h id=h6 name=ddd parentid=h1/>
<h id=h7 name=eee parentid=h1/>
</h>
Could some one guide me as to how to get this. I did write a stylesheet which gives me the following output.
<h id=h1 name=xxx>
<h id=h2 name=bbb parentid=h1/>
<h id=h3 name=ccc parentid=h2/>
<h id=h4 name=fff parentid=h3 systemid=s1>
<h id=h5 name=ggg parentid=h3 systemid=s2>
</h>
<h id=h6 name=ddd parentid=h1/>
<h id=h7 name=eee parentid=h1/>
</h>
As you can see I am missing the closing of the tag on the 7th line in the desired format. I have written the following stylesheet.
<!-- Hierarchy.xsl: Transform ROWSET/ROW format to the required Hierarchy format. -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Template for matching the rowset..... -->
<xsl:template match="HIERARCHY">
<HIERARCHY><xsl:apply-templates/></HIERARCHY>
</xsl:template>
<!-- Template for matching the row .... -->
<xsl:template match="HELEMENT">
<xsl:choose>
<xsl:when test="PARENT_ID=0">
<helement id="{ID}" name="{NAME}" parentid="{PARENT_ID}"/>
</xsl:when>
<xsl:when test="PARENT_ID!='0'">
<helement2 id="{ID}" name="{NAME}" parentid="{PARENT_ID}">
<xsl:for-each select="SYSTEMS/SYSTEMS_ROW">
<helement3 id="{HID}" name="{HNAME}" parentid="{HPARENT_ID}" systemid="{FORMATTED_SYSTEM_ID}">
</helement3>
</xsl:for-each>
</helement2>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Is there any way of achieving this. Any help would be appreciated. I am using XSQL to generate first the basic XML output and then applying stylesheet to achieve the desired output.
Sincerely,
DHello,
I have to write a style sheet to convert XML generated from XSQL into a different format. The query that I have is as follows.
select LEVEL depth,
'H' || hierarchy_id id,
name,
nvl2(parent_id, 'H' || parent_id, 0) parent_id,
CURSOR(select LEVEL depth,
'H' || hierarchy_id hid,
name hname,
nvl2(parent_id, 'H' || parent_id, 0) hparent_id,
decode(system_id, NULL, '0', 'S' || system_id) formatted_system_id,
system_id
from hierarchy
where parent_id = h.hierarchy_id
and system_id is not null
) as systems
from hierarchy h
where system_id is null
start with parent_id is null
connect by prior hierarchy_id = parent_id
The hierarchy table has a self join to itself. The selfjoin is on the hierarchyid and the parentid fields which is evident from the query.
Here the hierarchy table contains the parent system and also the child systems underneath. The problem is that the no. of levels that it can go deep is not fixed. The output of this in sqlplus is as follows.
Depth Hierarchyid, name parentid
1 h1 xxx <null>
2 h2 bbb h1
3 h3 ccc h2
<Cursor for systems>
hid hname hparentid formatted_system_id systemid
h4 ccc h2 s1 1
h5 ccc h2 s2 2
<Back to original data>
Depth Hierarchyid, name parentid
2 h6 ddd h1
2 h7 eee h1
The desired output required from the stylesheet is as follows
<h id=h1 name=xxx>
<h id=h2 name=bbb parentid=h1>
<h id=h3 name=ccc parentid=h2>
<h id=h4 name=fff parentid=h3 systemid=s1>
<h id=h5 name=ggg parentid=h3 systemid=s2>
</h>
</h>
<h id=h6 name=ddd parentid=h1/>
<h id=h7 name=eee parentid=h1/>
</h>
Could some one guide me as to how to get this. I did write a stylesheet which gives me the following output.
<h id=h1 name=xxx>
<h id=h2 name=bbb parentid=h1/>
<h id=h3 name=ccc parentid=h2/>
<h id=h4 name=fff parentid=h3 systemid=s1>
<h id=h5 name=ggg parentid=h3 systemid=s2>
</h>
<h id=h6 name=ddd parentid=h1/>
<h id=h7 name=eee parentid=h1/>
</h>
As you can see I am missing the closing of the tag on the 7th line in the desired format. I have written the following stylesheet.
<!-- Hierarchy.xsl: Transform ROWSET/ROW format to the required Hierarchy format. -->
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="@*|node()"/>
</xsl:copy>
</xsl:template>
<!-- Template for matching the rowset..... -->
<xsl:template match="HIERARCHY">
<HIERARCHY><xsl:apply-templates/></HIERARCHY>
</xsl:template>
<!-- Template for matching the row .... -->
<xsl:template match="HELEMENT">
<xsl:choose>
<xsl:when test="PARENT_ID=0">
<helement id="{ID}" name="{NAME}" parentid="{PARENT_ID}"/>
</xsl:when>
<xsl:when test="PARENT_ID!='0'">
<helement2 id="{ID}" name="{NAME}" parentid="{PARENT_ID}">
<xsl:for-each select="SYSTEMS/SYSTEMS_ROW">
<helement3 id="{HID}" name="{HNAME}" parentid="{HPARENT_ID}" systemid="{FORMATTED_SYSTEM_ID}">
</helement3>
</xsl:for-each>
</helement2>
</xsl:when>
<xsl:otherwise>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
</xsl:stylesheet>
Is there any way of achieving this. Any help would be appreciated. I am using XSQL to generate first the basic XML output and then applying stylesheet to achieve the desired output.
Sincerely,
D -
Need help with self join query
Hello,
I have table A with the following data
oid parent_oid
10 4
4 2
2 2
12 6
6 6
parent_oid is the parent of oid. I'd like a query that shows the final parent of the oid. The result should show the following
oid final parent
10 2
4 2
2 2
12 6
6 6
I'm using Oracle 10g. I'm familiar with self joins, but that alone will not do the job. Thanks!Hi,
arizona9952 wrote:
... I'm familiar with self joins, but that alone will not do the job.You're absolutely right!
A 2-way self join would work for rows have no parent, or rows that are directly connected to their final ancestor (such as oid=4), but not for anything farther away.
A 3-way self-join would work for one more level away from the final row, but no more. That would be enough for the small set of sample data that you posted, but it would not work if you added a new row with parent_id=10.
An N-way self-join would work for up to N+1 levels, but no more.
You need something that can go any number of levels, such as CONNECT BY:
SELECT CONNECT_BY_ROOT oid AS oid
, parent_oid AS final_parent
FROM a
WHERE CONNECT_BY_ISLEAF = 1
CONNECT BY oid = PRIOR parent_oid
AND oid != parent_oid
;Edited by: Frank Kulash on Feb 22, 2010 7:09 PM
Upon sober reflection, I think that a Top-Down query, like the one below, would be more efficient than a Bottom-Up query, like the one above:
SELECT oid
, CONNECT_BY_ROOT parent_oid AS final_parent
FROM a
START WITH parent_oid = oid
CONNECT BY parent_oid = PRIOR oid
AND oid != PRIOR oid
; -
Hello all,
How to create a self join using ABAP Query?
Say, I have this table EKBE with belnr (materials doc num) and lfbnr (reference material doc num). I have to pick the PO's from EKBE whose belnr doesnt have any lfbnr.
Regards
Madhumathi Ahi madhu,
tables : ekbe.
data itab like standard table of ekbe with header line.
select * from ekbe into table itab where belnr >< 0 and lfbnr = ' '.
loop at itab.
write :/ itab-belnr,itab-lfbnr.
endloop.
check this code this works to select the orders whose belnr doesnt have any lfbnr
reward points if useful. -
Cross-listing Query (Partition By Clause? Self-Join?)
Hello,
I need a query that will cross-list courses a professor is teaching this semester. Essentially, two fields need to be the same (i.e.: Section & CourseTitle), while the third field is different (i.e.: Subject).
For example, Max Power is a professor teaching 3 courses, one is cross-listed (ENG 123 and JRL 123):
LastName FirstName Subject Section CourseTitle
Power Max ENG 123 English Composition
Power Max ENG 452 Robert Frost Poetry
Power Max JRL 123 English Composition
Power Max ENG 300 Faulkner & TwainThe desired query output is this:
LastName FirstName Subject Section CourseTitle
Power Max ENG 123 English Composition
Power Max JRL 123 English CompositionBasically, I need only the cross-listed courses in the output.Is this an instance where I use a "Partition By Clause" or should I create a self-join?
Much thanks for any help and comments.Unfortunately, I can't create new tables. I don't have permission. I can't alter, add or delete any of the data.
So I tried Frank's code with my data:
WITH got_cnt AS
SELECT sivasgn_term_code, spriden_id, spriden_last_name, spriden_first_name,
ssbsect_ptrm_code, ssbsect_camp_code,
sivasgn_crn, ssbsect_subj_code, ssbsect_crse_numb, scbcrse_title,
count(*) over (partition by ssbsect_crse_numb, scbcrse_title) cnt
FROM spriden INNER JOIN sivasgn ON spriden_pidm = sivasgn_pidm JOIN
ssvsect ON ssbsect_crn = sivasgn_crn JOIN
sfrstcr ON sfrstcr_crn = sivasgn_crn
WHERE ssbsect_term_code= sivasgn_term_code
AND sfrstcr_term_code = sivasgn_term_code
AND ssbsect_enrl > '0' and sivasgn_credit_hr_sess > '0'
AND sivasgn_term_code IN ('200901', '200909')
AND spriden_change_ind IS NULL
AND ssbsect_camp_code IN ('1', '2', 'A', 'B')
SELECT DISTINCT sivasgn_term_code, spriden_id, spriden_last_name, spriden_first_name,
substr(ssbsect_ptrm_code,1,1) as ptrm_code, ssbsect_camp_code,
sivasgn_crn, ssbsect_subj_code, ssbsect_crse_numb, scbcrse_title
FROM got_cnt
WHERE cnt >1
ORDER BY spriden_last_name, sivasgn_term_code, ssbsect_crse_numb;The output pretty much displays all courses with same subject code, course number and course title.
Output:
LastName FirstName Subject Section CourseTitle
Power Max ENG 123 English Composition
Power Max ENG 123 English Composition
Power Max ENG 452 Robert Frost Poetry
Power Max ENG 452 Robert Frost Poetry
Power Max ENG 300 Faulkner & Twain
Power Max ENG 300 Faulkner & Twain
Power Max JRL 123 English Composition
Power Max JRL 123 English CompositionWhat I would like is same course number, course title, BUT different subject code. Pretty much that in my first post of this thread.
Desired Output:
LastName FirstName Subject Section CourseTitle
Power Max ENG 123 English Composition
Power Max JRL 123 English CompositionMaybe I'm explaining this wrong. Any help would be greatly appreciated. Thanks. -
Self Joining and Inline Query. A tricky report.
I am stuck with a very tricky situation.Please help.This is PROD issue.
I have written a SQL code which has 1 inline queries,and displays the right results
with the right report output
Dont get confused.Just go thru this.
select pie.id_inst_code,
ISNULL(PN.Active, 0) 'Active',
from position_master_input_event pie,
(select insx.id_inst_xref_type,insx.id_inst_xref,count(*) 'PrimaryListing'
from instrument ins, instrument_xref insx
where ins.id_inst = insx.id_inst
and insx.flg_active = 'Y'
and ins.flg_active = 'Y'
group by insx.id_inst_xref_type,insx.id_inst_xref
)PN
where id_entity = 'AGL'
and pie.id_inst_code *= PN.id_inst_xref
and pie.id_src_inst_code_type*= PN.id_inst_xref_type
group by pie.id_inst_code,PN.Active,
Table :Instrument_xref
id_inst id_inst_xref_type id_inst_xref flg_active
0372285 SE B0DV8Y9 Y
0372285 IS GB00B03MLX29 Y
Table :Instrument
id_inst id_inst_xref_type id_inst_xref flg_active flg_primary_listing
0372285 SE B0DV8Y9 Y N
OUTPUT:
id_inst_xref Active
B0DV8Y9 1
PERFECT.Works fine
2) Now comes the tricky part.:
0372285 also has GB00B03MLX29 which has flg_active to Y and which also maps to 0372285.
Am I right?
New reportOutput
id_inst_xref Active PRIMARY ISIN
B0DV8Y9 1 1
So,now I want a SELF JOIN this way built into the code:
(hardcoded values work)
(i)
select a.id_inst_xref
from instrument_xref a,
instrument_xref b
where b.id_inst_xref ='B0DV8Y9'
and b.id_inst = a.id_inst
and b.id_inst_xref_type in ('SE','IS')
and a.id_inst_xref = 'GB00B03MLX29'
(ii)
select count(*) 'PrimaryISIN'
from instrument ins,
instrument_xref insx
where ins.id_inst = insx.id_inst
and insx.flg_active = 'Y'
and ins.flg_primary_listing = 'Y'
and ins.flg_active = 'Y'
And now LINKING ALL :
select pie.id_inst_code,
ISNULL(PN.Active, 0) 'Active',
from position_master_input_event pie,
(select insx.id_inst_xref_type,insx.id_inst_xref,count(*) 'PrimaryListing'
from instrument ins, instrument_xref insx
where ins.id_inst = insx.id_inst
and insx.flg_active = 'Y'
and ins.flg_active = 'Y'
group by insx.id_inst_xref_type,insx.id_inst_xref
)PN,
(select count(*) 'PrimaryISIN'
from instrument ins,
instrument_xref insx
where ins.id_inst = insx.id_inst
and insx.flg_active = 'Y'
and ins.flg_primary_listing = 'Y'
and ins.flg_active = 'Y'
and insx.id_inst_xref = (
select DISTINCT a.id_inst_xref
from instrument_xref a,
instrument_xref b
where b.id_inst_xref = 'B0DV8Y9'
and b.id_inst = a.id_inst
and b.id_inst_xref_type in ('SE','IS')
and a.id_inst_xref = 'GB00B03MLX29'
where id_entity = 'AGL'
and pie.id_inst_code *= PN.id_inst_xref
and pie.id_src_inst_code_type*= PN.id_inst_xref_type
group by pie.id_inst_code,PN.Active,
THE Self join works fine as long as it is hardcoded.
But assume there can br multiple such situations as the above,and I dont want to
hardcode the values,how can I build the NEW REPORT by SELF JOINING.
Please can someome help.This is a tricky one.
Is there a better way to thisIsn't this the same question as:
Passing values dynamically Froman 'INLINE Query' to a 'SUB QUERY'
and
Another query regarding Inline Query and Self Join and pass Column Values -
MSS custom query restrictions (table/view/join)
Dear all,
We are currently trying to integrate a sap query which also gathers data from event management. This query is based on an infoset and a table view and not on a logical database.
When executing the query within the portal (generictableview iview) we get the error message "No data records found". While debugging the function module HR_INFO_GET_USING_QUERY which is called here we found out that the error message is generated because no logical database is retrieved.
Therefore my question is: are mss queries in portal restricted to queries which are based on logical databases only or can we create and use queries in portal which are based on table/views/joins?
Any help on this issue is greatly appreciated!
Thanks already very much in advance,
HelgaHello MIG,
I am still searching and I have not found a solution yet.
Interestingly enough the query can be executed without any problems in R/3 but not from the portal iView. Therefore I am wondering if it is only a restriction on the MSS side.
@forum users: did anyone of you face this problem and has a solution to it?
Thanks very much for any input on this!
Kind regards,
Helga -
Self join with fact table in Obie 10G
I am a newbie to obiee.I have a development requirement as follows-
I need to find supervisors designation with the existing star RPD design. explanation is below
DIM_Designation(Desig_Wid)
|(Row_wid)
|
DIM_EMPLOYEE--------WORKER_FACT------------DIM_Supervisor
(Row_Wid)-----------------(Employee_Wid)
(Supervisor_Wid)------------(Row_Wid)
3 dimension is joined to fact to get employee, his supervisor and designation of employee. now i want to get the supervisor's designation? how is it possible? already employee and supervisor dimension is same W_employee_d table joined with fact as alias DIM_EMPLOYEE and DIM_SUPERVISOR. how to do self join with fact to get supervisor's designation. i do not have any supervisor_desig_wid in fact table. any help is deeply appreciated.Yes,Duplicate the fact table create a primary key on the newly fact table alias dimension table.So you can ur data modelling as usual.
-
Self-join query to Analytical function query
Hi All,
I have converted a self-join query to Analytical function query due to the performance reasons.
Query which is using Analytical function is giving the correct count as I compared it with query using Self-Join. Can you please tell what is wrong in the query.
==========================
Query using Self-Join
select count(1)
From (select t1.*, max(t1.dw_creation_dt) over (partition by t1.empl_id) pers_max_date
from ohr_pers_curr t1 ) pers
, (select t2.*, max(t2.dw_creation_dt) over (partition by t2.empl_id, t2.empl_rcd) job_max_date
from OHR_JOB_CURR t2) job
where pers.empl_id = job.empl_id
and pers.dw_creation_dt=pers.pers_max_date
and job.dw_creation_dt=job.job_max_date
and job.dummy_row_flag = 'N'
and pers.dw_creation_rsn_cd in ('N', 'U')
and job.dw_creation_rsn_cd in ('N', 'U')
================================================
Query Using Analytical function
select count(1)
From (select t1.*, max(t1.dw_creation_dt) over (partition by t1.empl_id) pers_max_date
from ohr_pers_curr t1 ) pers
, (select t2.*, max(t2.dw_creation_dt) over (partition by t2.empl_id, t2.empl_rcd) job_max_date
from OHR_JOB_CURR t2) job
where pers.empl_id = job.empl_id
and pers.dw_creation_dt=pers.pers_max_date
and job.dw_creation_dt=job.job_max_date
and job.dummy_row_flag = 'N'
and pers.dw_creation_rsn_cd in ('N', 'U')
and job.dw_creation_rsn_cd in ('N', 'U')
==================================Hi David,
The base is same but the problem is different.
As far as implementation concern these queries looks same, but when I see there counts, they do not match. I do not have any reason why this happening.
Regards
Gaurav -
Deleting records from a recursive table query
Hi All,
I have the follow query, I would like to ask for your help, please: we use recursive tables for various purposes and one of them may have 100,000's records.
What would be the best approach to delete records from such a table?
I was thinking about two below, but any additional one will be more than welcome as well:
(1) I can DELETE FROM my_table WHERE my_table_id IN (SELECT my_table_id FROM my_table START WITH my_table_parent_id = X CONNECT BY PRIOR my_table_id = my_table_parent_id, but it means that I will run on my_table twice, no?
(2) I thought also to create a Foreign Key of my_table_id REFERENCES my_table_parent_id, but then I am afraid it will effect DML commands on that table.
Thank you in advanceHi,
kdwolf wrote:
... (1) I can DELETE FROM my_table WHERE my_table_id IN (SELECT my_table_id FROM my_table START WITH my_table_parent_id = X CONNECT BY PRIOR my_table_id = my_table_parent_id, but it means that I will run on my_table twice, no?Sorry, I'm not sure whqt you mean by "I will run on my_table twice". Assuming you don't already have a foreign key constraint (as you described below) I don;t know any other way, let alone a more efficient way, to get the same results.
(2) I thought also to create a Foreign Key of my_table_id REFERENCES my_table_parent_id, but then I am afraid it will effect DML commands on that table.You're right; a foreign key constraint always costs a little whenever you do DML. Someone who knows your application and your system as well as you do will have to decide if the benefit of having accurate, consistent data justifies that additional cost. If you're not sure, I suggest you add the constraint.
One advantage of having a foreign key constraint is that you can create it with the "ON DELETE CASCADE" option. Then, if you simply say "DELETE FROM my_table WHERE my_table_patrent_id = X", all the descendants of those rows will automatically be deleted, exactly as you requested in (1) above. -
Optimizing the query containing 7 table joins
hi,, I have a query which is taking almost 20 minutes to retrieve the data from DB. let me know how can i further optimize the query.. the tables contains huge amount of data
Table1 a -> 1040131 rows
Table2 b -> 1040131 rows
Table3 c -> 2080262 rows
Table4 d -> 2749 rows
Table5 e -> 1040131 rows,
Table6 f -> 93819 rows
Table7 g -> 99203 rows
My query is
SELECT a.lid, g.image, f.product , d.manufacturer, b.desc, c.price, c.abbr, c.currency, c.class
FROM
Table1 a,
Table2 b,
Table3 c,
Table4 d,
Table5 e,
Table6 f,
Table7 g
WHERE (UPPER(b.desc) like '%TEST%' OR UPPER(b.desc) like '%BEST%')
and a.line = b.line
AND a.line = c.line
AND c.subset = 576
AND a.manufacturer = d.manufacturer
AND a.line = e.line
and a.product = f.product
and e.image = g.image
Please tell me how can i optimize this query further to work fasteruser1708333 wrote:
WHERE (UPPER(b.desc) like '%TEST%' OR UPPER(b.desc) like '%BEST%')
I would imagine that that line is the main culprit.
You are doing a free text search which will always result in a full table scan the way you are doing it.
If you need free text searching then you should consider using [Oracle Text|http://www.oracle.com/technology/products/text/index.html]
Maybe you are looking for
-
Powerbook's dead after Hard DRIVE is replaced.
Please help. I was about to sell my 17 in since I bought the mac book pro and I wanted to keep my 100 gig and put the original 80 back. I opened it (following mac fixit guidelines) but after closing everything. I have NO power. I re did every connect
-
how to hard reset iphone ?
-
Weird colour behaviour in JTextField
Hi, I've set the background color of my JTextFields, but they keep on changing hue, and fragments of text on the JPanel - for example, text from buttons, or from titles appear in the JTextFields. I've set the color like this: Color mandatory = new Co
-
What does the "option" input of the FIR Windowed Coefficients VI do?
Here's the LV Help entry: option specifies whether to scale the FIR Windowed Coefficients. The default is 0. 0 not scaled-Does not scale the FIR Windowed Coefficients. 1 scaled-Scales the FIR Windowed Coefficients. Well that's....unhelpful. Scales th
-
Adding complicated selections to Eclipse Link CriteriaBuilder ?
Hi all, Can any body suggest how to add select case when to_char(trunc(TO_DATE ('03-APR-2015','DD-MM-YYYY'), 'mm'), 'FMDAY') = 'SUNDAY' then to_number(to_char(TO_DATE ('03-APR-2015','DD-MM-YYYY'), 'W'))+1 else ceil((to_char(TO_DATE ('03-