Self Join Problem (I Think)
I have a table (that I inherited) that has the following fields - emp num, emp first name, emp last name, emp title, emp salary, emp manager - etc. There is no manager table - the emp manager field is a the emp num that was assigned to the employee who was a manager. What I need is to create a manager’s report that includes the following: manager’s first and last name, number of employees that he/she manages, the total salary for their employees. I am already stuck with just the basic part of it - this is what I have so far:
SELECT man.EMP_MANAGER, man.EMP_LNAME, man.EMP_FNAME,
count(emp.EMP_NUM)
FROM EMPLOYEE man, EMPLOYEE emp
GROUP BY EMP_MANAGER
The error I get is
GROUP BY EMP_MANAGER
ERROR at line 4:
ORA-00918: column ambiguously defined
Any thoughts on how I get this to work properly?
Ok - I added the additional group by that was recommended and it is starting to work but not exactly - it is listing all the manager id - next to each employee name and gives the individual salary and total count as one. There are two managers - I am trying to get it to group the employees for each of the two - and get the total number of employees for each manager.
Here are the adjustments I have made - I don't get an error but the data isn't correct.
SELECT man.EMP_MANAGER, man.EMP_LNAME, man.EMP_FNAME,
AVG(emp.EMP_SALARY)"Employee AVG. Salary", count(emp.EMP_NUM)"Total Employees"
FROM HARTMAR.EMPLOYEE man, HARTMAR.EMPLOYEE emp
Where man.EMP_MANAGER = emp.EMP_NUM
GROUP BY man.EMP_MANAGER, man.EMP_LNAME, man.EMP_FNAME
Any suggestions?
Similar Messages
-
SQL> desc messages;
Name Null? Type
MESSAGEID NOT NULL NUMBER
TITLE NOT NULL VARCHAR2(50)
AUTHOR VARCHAR2(20)
BODY NOT NULL VARCHAR2(4000)
BOARD NUMBER
THREAD NOT NULL NUMBER
DATE_CREATED NOT NULL DATE
This is the table i need to do a self join on, i know the two queries individually but i need to have them in one join,,,
select b.title,b.boardid,m.messageid,m.title,m.author,m.date_created,m.body
from messages m, boards b where b.boardid=m.board and m.thread=0 and b.boardid='198'
and m.messageid='241';
Thread title Author Starting message Last post
Austrailia noel Austrailia 04/01/2005 21:22:35
-----selects replies to the above message-----------
select author,date_created,body
from messages
where board=198 and thread=241;
AUTHOR DATE_CREATED BODY
noel 05-JAN-05 Oz is played on clay
noel 05-JAN-05 Oz played on grass
noel 05-JAN-05 Oz played on grass
This is the output that i want but at the moment thread title is repeated for all four rows returned.I want the output to look like a reply to a message like you see in some message boards on the web,,, you have the starting message and underneath you see the replies
Thread title Author Starting message Last post
Austrailia noel Austrailia 04/01/2005
noel Oz is played on clay 05-JAN-05
noel Oz played on grass 05-JAN-05
noel Oz played on grass 05-JAN-05Please please please do not post duplicate threads. It makes it hard for people to follow what's going on. And it's annoying to boot. I think this is the third thread you have started on this topic.
Please remember we are volunteers here, not Oracle employees. We do the best we can to answer queries in a timely fashion but if you want snappier service then I'm afraid you'll need to pay for a support contract.
You posted a rejoinder to Barbara's answer to your other thread URGENT: combining two sql statements. That is sufficient to keep your issue in the public arena.
Thank you for your co-operation.
Regards, APC
Issued in memory of the Rogue Moderators -
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 -
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
; -
How to achieve parent-child relationship using self join?
my table structure is as follows
parent child name
-1 1 A1
1 2 A2
1 3 A3
how to achieve the hierarchy model using self join. this can be easily achieved using "connect by prior". but how to achieve the same using self join?Hi,
Yes, that's definitely possible. If you only need to display two levels from the hierarchy, a self-join is a good option. Make it an outer join if you need to show everyone on one level, regardless of whether they have a match on the other level or not; for example, if you want the output:
child_name child_id parent_name parent_id
A1 1
A2 2 A1 1
A3 3 A1 1It's good that you posted some sample data. Now post the results you want from that data, and your query (what you think is the best attempt you've made so far). If you haven't tried anything so far, then look at some other simple self-join to get ideas. -
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
; -
How to write self join in sql?
Hi,
I have table named "table_upload", column "record_type" value "01,03,04....." and start_date,end_date and so on
And i will have value for start_date,end_date only for record_type=01,rest of type these two columns will be null.
now i need to write query with self join, to include above concept. can any one please help me .
and my query look like follows,I just want to re write
Please provide DDL+DML + expected output!
and short explanation what is it that we all ask you for:
DDL = Data Definition Language. In our case that is, CREATE TABLE statements for your tables and other definitions that are needed to understand your tables structure and there for let us to test and reproduce the problem in our server. Without DDL no one
can execute any query.
How to get DDL: Right click on the table in Object Explorer and select script table as CREATE. Post these create table scripts here.
DML = data manipulation language is a family of queries used for manipulating the data it self like: inserting, deleting and updating data. In our case we need some sample data in order to check the query and get result, so we need some indert query for
sample data.
If you post a "create table query" for the tables and "insert <table> query" with some sample, then we could help you without Assuming/Guessing. There is a reason that DDL is generally asked for and expected when discussing query problems - it helps
to identify issues, clarify terminology and prevent incorrect assumptions. Sample data also provides a common point of reference for the discussion. A script that can be used to illustrate or reproduce the issue you have, will encourage others to help.
[Personal Site] [Blog] [Facebook] -
Hi,
I want to make an application using component tree with one table. This table has menu_id and menu_parent.
I got a little problem when I use self joining table, it shown all parents and children.
I want only the root folder (parent) to be shown first and then by opening the menu_parent, i should be able to see the menu_id folders.
Can you please help me.
ThanksHi,
you need to have a viewcriteria in your vo for selecting the parents one, then while selecting vo in datacontrols in AM you need to select your viewcriteria in your vo by editing it.
Also you need to have a ViewLink between same viewobjects i.e menu_id->parent->id.
See if this helps.
Regards,
Santosh, -
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 -
I would be very grateful if someone would show me show to use the self join, I understand what is does but just don't know how to use it. I have a question from a exercise but no answer so I can't check it the question is - using temporary labels to abbreviate table names, find all the staff that earn more than 'SONG'.
here is the table
STAFFID SNAME JOB MGR STARTDATE SAL COMM BRANCHID
5963 SMITH ADMIN 5209 15-NOV-00 1600 20
5994 BATES ASSISTANT 5896 20-FEB-01 1800 100 30
5125 CHAN ASSISTANT 5896 22-FEB-02 1550 150 30
5665 JONES MANAGER 5938 02-MAR-01 3100 20
5465 WILSON ASSISTANT 5896 28-OCT-00 1250 140 30
5896 HAYAT MANAGER 5938 01-MAY-01 3100 30
5287 CLARK MANAGER 5938 09-JUL-02 3100 10
5887 COSTA BUYER 5665 18-APR-04 3150 20
5938 SHAW DIRECTOR 17-NOV-01 7000 10
5484 TURNER ASSISTANT 5896 08-OCT-01 1550 0 30
5678 KALIM ADMIN 5887 23-APR-04 1600 20
5009 JAMES ADMIN 5896 03-DEC-01 1600 30
5209 SONG BUYER 5665 03-JAN-02 3000 20
5439 SIMPSON ADMIN 5287 23-FEB-02 1600 10
Thanks in advanced :)
Edited by: user11093259 on 01-Dec-2010 10:19Hi,
Welcome to the forum!
Always post your best attempt at solving the problem. You'll get more specific replies that will help you learn more, and it often clarifies what you're trying to do.
Here's a typical self-join, using the scott.dept table (which you probably have avaialble).
SELECT l.dname AS lower_dname
, h.dname AS higher_dname
FROM scott.dept l
JOIN scott.dept h ON l.dname < h.dname
;Output:
LOWER_DNAME HIGHER_DNAME
ACCOUNTING OPERATIONS
ACCOUNTING RESEARCH
ACCOUNTING SALES
OPERATIONS RESEARCH
OPERATIONS SALES
RESEARCH SALESAs you can see, this pairs every higher_dname with every dname that is less than it.
This is very similar to your problem. The main difference is, where the query above shows every possible higher_dname (and the lower_dnames related to it), you're interested in a single, specific higher value (and the rolws with lower values related to it). You can restrict the query to show only that one, specific higher values by adding a WHERE clause. Try it. If you get stuck, ask a more specific question, and, remember, post your code. -
Self join vs Hierarchical Queries
Hi,
please tel me which one 1 should use ?
i have to get simple manger's employ list, should i use self join or hierarchical queries(CONNECT BY and prior)?
yours sincerelyHi,
944768 wrote:
Hi,
please tel me which one 1 should use ?
i have to get simple manger's employ list, should i use self join or hierarchical queries(CONNECT BY and prior)?It depends on your data and your requirements.
Whenever you have a question, please post a little sample data (CREATE TABLE and INSERT statements) for all the tables involved, so the people who want to help you can re-create the problem and test their ideas. Also post the results you want from that data, and an explanation of how you get those results from that data.
Explain, using specific examples, how you get those results from that data.
If you can show what the problem is using commonly available tables (suc as scott.emp, which has a 4-level hierarchy) then you don't have ot post any sample data, just the results and the explanation.
Always say what version of Oracle you're using (e.g. 11.2.0.2.0).
See the forum FAQ {message:id=9360002}
If your hierarchy consists only of 2 levels, then a self-join will probably be more efficient, simpler to code, and easier to maintain.
If you don't know how many levels are in the hierarchy, then self-join isn't an option. Use CONNECT BY or, if you have Oracle 11.2, a recursive WITH clause.
If you have a fixed number of levels (or an upper bound) greater than 2, then CONNECT BY (or a recursive WITH clause) will probably be best. -
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 -
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.
-
How to tune self join query in Oracle 11g
Oracle & SQL new to me,and I'm still in learning phase.
Could you please help me to tune below oracle query?? This table contains ~95 lac records and it takes 1 hour to retrieve data using this query.
Your suggestions/comments/help will be appreciated.
Thanks in advance.
SELECT A.CNO AS CNO, A.FNO AS FNO, A.CID AS CID, A.IID AS IID
FROM CAC_LKP A, (SELECT C_DATE, CNO, FNO
FROM (SELECT MAX(CAC_LKP.C_DATE) AS C_DATE, CAC_LKP.CNO AS CNO, CAC_LKP.FNO AS FNO
FROM CAC_LKP
WHERE ACTIVE = 'Y' GROUP BY CNO, FNO)) B
WHERE A.C_DATE = B.C_DATE
AND A.CNO = B.CNO
AND A.FNO = B.FNO
AND A.ACTIVE = 'Y'
Primary key is defied over combination of c_date,iid,active.
Edited by: 1009236 on Jun 1, 2013 12:52 AM>
SELECT A.CNO AS CNO,
A.FNO AS FNO,
A.CID AS CID,
A.IID AS IID
FROM CAC_LKP A,
SELECT C_DATE,
CNO,
FNO
FROM
SELECT MAX(CAC_LKP.C_DATE) AS C_DATE,
CAC_LKP.CNO AS CNO,
CAC_LKP.FNO AS FNO
FROM CAC_LKP
WHERE ACTIVE = 'Y'
GROUP BY CNO, FNO
) B
WHERE A.C_DATE = B.C_DATE AND
A.CNO = B.CNO AND
A.FNO = B.FNO AND
A.ACTIVE = 'Y';Hi,
Before even starting to see why there is a performance problem, I think you should consider the fact that there is logical problem in your WHERE clause. According to what you mentioned the primary key is composed of *(c_date, iid, active)* yet iid is absent in both the global query's WHERE clause and also that of the subquery.
Consequently the (aggregate) rows in the subquery will not be linked based on a correct logic to the external query.
Regards,
Dariyoosh -
Oracle doc inconsistent on materialize view with union all and self joins
First of all, I can't seem to create a materialized view containing self-joins AND union all. Is it possible?
I checked Oracle 9i (my version: PL/SQL Release 9.2.0.4.0 - Production) documentation and I get different answers (or so it seems to me).
First I saw this: "The COMPATIBILITY parameter must be set to 9.0 if the materialized aggregate view has inline views, outer joins, self joins or grouping sets and FAST REFRESH is specified during creation..."
Did you see the part about 'self joins' in there? I did and I was pumped because that seems to say that you CAN have 'self joins' (and my compatibility is 9.2...)
BUT
In the very same document I also found "Oracle does not allow self-joins in materialized join views." (rage)
You can see the document I am speaking of here: http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96520/mv.htm#574889
Whenever I try to create the mview I get the following error. (
In any caseORA-01446 cannot select ROWID from view with DISTINCT, GROUP BY, etc.First of all, I can't seem to create a materialized view containing self-joins AND union all. Is it possible?
I checked Oracle 9i (my version: PL/SQL Release 9.2.0.4.0 - Production) documentation and I get different answers (or so it seems to me).
First I saw this: "The COMPATIBILITY parameter must be set to 9.0 if the materialized aggregate view has inline views, outer joins, self joins or grouping sets and FAST REFRESH is specified during creation..."
Did you see the part about 'self joins' in there? I did and I was pumped because that seems to say that you CAN have 'self joins' (and my compatibility is 9.2...)
BUT
In the very same document I also found "Oracle does not allow self-joins in materialized join views." (rage)
You can see the document I am speaking of here: http://download-west.oracle.com/docs/cd/B10501_01/server.920/a96520/mv.htm#574889
Whenever I try to create the mview I get the following error. (
In any caseORA-01446 cannot select ROWID from view with DISTINCT, GROUP BY, etc.
Maybe you are looking for
-
Problem in reading BMP file .....
I've facing some inconsistency in reading BMP headers. There are two of them, and I've outlined them below.... Here's a description of the BMP headers, just for refreshing .... 1. typedef struct { BITMAPFILEHEADER bmfHeader; BITMAPINFO
-
Hi, I am creating the BP by using BAPI_BUPA_FS_CREATE_FROM_DATA2 In the IDENTIFICATION tab we have ID type, Identification Number,responcible person etc. Can any one let me know how to create BP with data in above fields from the Bapi. Thanks. Muru.
-
Anyone ever had this problem?
An Audio Instrument track with a send to a stereo bus is still heard when muted. The send is definitely post fader but the sound is escaping to the bus. Even disabling the send has no effect. Changing the send from post to pre and back again works .
-
Old Lion Finder bug reappears in Mountain Lion -- lost options
There were a number of problems with the Finder View options under Lion which were fixed bit-by-by, upgrade-by-upgrade. In general, folder placement was scrambled and view options were lost/reset after certain operations. Now, with Mountain Lion, som
-
HT1212 how do i unlock my ipod
My ipod is locked and i cant open it.It says ipod disabled try again in 22,718,624 minutes! How can i reset it?