Hierarchical Query CONNECT BY Oracle - oracle

I am trying to implement the Connect By query in oracle. Trying to understand how it works. So I have a simple table
which looks likes:
empno ename mno
1 KS null
2 AB 2
3 BC 1
4 TR 3
5 QE 2
6 PL 3
7 LK 6
The Query
SELECT empno, ename, mno
FROM test
START WITH ename = 'LK'
CONNECT BY PRIOR empno = mno;
So when the name is LK I should get the following parent/child rows LK>PL>BC>KS.
The SQLFIDDLE But I am not getting the correct results. What I am doing wrong ?

No, you should not.
LK's parent is PL. PL's parent is BC. BC's parent is KS. KS has no parent. When you're trying to start tree from LK, you get all it's children - none, because there are no records with mno = 7.
You muddled parent-child order in your query. If you wish to unwind the three from leaf to root, you should ask
SELECT empno, ename, mno
FROM test
START WITH ename = 'LK'
CONNECT BY empno = PRIOR mno;
If you wish to see the tree into the natural order, you should to ask
SELECT empno, ename, mno
FROM test
START WITH mno is null
CONNECT BY PRIOR empno = mno;

Related

It is possible insert dummy (dash) into first row data use select statement in oracle SQL?

table_A
col_color col_name col_qty
- - - <----- dummy dash
RED APPLE 2
YEL BANANA 1
GRN GREEN_APPLE 3
Hi, it is posible to insert first row of dummy dash for viewing not store into database
use oracle sql plus ?
Anyone help is much apprecited.
One option is to UNION two data sets; one contains dummy dashes, while another contains "real" data. Note that dashes are considered to be strings, which means that you'll have to cast other datatypes to character datatype (see to_char(deptno) in my example):
SQL> with temp as
2 (select 1 rn, '-' deptno , '-' dname, '-' loc from dual
3 union all
4 select 2 rn, to_char(deptno), dname , loc from dept
5 )
6 select deptno, dname, loc
7 from temp
8 order by rn, deptno;
DEPTNO DNAME LOC
---------- -------------- -------------
- - -
10 ACCOUNTING NEW YORK
20 RESEARCH DALLAS
30 SALES CHICAGO
40 OPERATIONS BOSTON
SQL>
The rn column is used to correctly sort the output (dashes first, the rest of data next).
If you don't want to use 'with', then how about this?
(
SELECT '-' COL_COLOR
, '-' COL_NAME
, '-' COL_QTY
FROM DUAL
)
UNION ALL
(
SELECT *
FROM table_A
)
I think this way is the best way not using 'with'.

Getting manager & managers manager number in oracle

I have below table in oracle
EMPNO ENAME MGR
1 A 1
2 B 1
3 C 2
4 D 3
5 F 1
6 G 3
7 H 6
I need to pass a EMPNO and it should give me manger id and if manager has another manager it should give me there id's too in the same field.
For example, If I pass empno = 7 then the output should be 6,3,2,1.
You can use the connect by syntax to create a hierarchical query:
SELECT mgr
FROM emp
START WITH empno = 7
CONNECT BY PRIOR empno = mgr
Here is the query, I used finally for the actual results
SELECT ENAME,
CONNECT_BY_ISCYCLE Cycle,
LEVEL,
SYS_CONNECT_BY_PATH(ENAME, '/') Path
FROM EMP_DEMO
START WITH empno = '7'
CONNECT BY NOCYCLE PRIOR MGR = EMPNO;
You always have to take the max level record.

Not sure how to write connect by clause

I have the following query to find employees who are not managers in the EMP table of oracle
select * from emp e1
where not exists (select null from emp e2
where e2.mgr=e1.empno)
I need output using start with connect by clause , thus avoiding self join
There is a function, CONNECT_BY_ISLEAF(), which indicates whether a given row in a hierarchical query is a leaf node. In the EMP table, employees who are not managers will be leaf nodes.
So, we can use this function in a nested hierarchical query to filter the non-managers:
select empno, mgr, ename
from (
select empno, mgr, ename, CONNECT_BY_ISLEAF cbi
from emp
start with mgr is null
connect by prior empno = mgr
) where cbi = 1
/
Oracle has several neat functions for interrogating hierarchies. Find out more.

Swap these two columns without using update in Oracle sql?

Ename sex
ABC male
Def female
Swap between male & female.
Output should be
Male ABC
Female DEF
Thanks in advance!
Preparing for Interview.
I'm going to assume you have a table defined like:
CREATE TABLE EMP
(ENAME VARCHAR2(20),
SEX VARCHAR2(6));
and that you have the following rows in it:
ENAME SEX
ABC male
Def female
I'll further assume that the output in your question was the result of executing
SELECT * FROM EMP
Now, to answer your question - to get SEX first, then ENAME, try the following:
SELECT SEX, ENAME FROM EMP
If you're trying to concatenate the values of SEX and ENAME so you get back a single column try
SELECT SEX || ' ' || ENAME AS SEX_AND_NAME FROM EMP
Share and enjoy.
The answer is as below: Assuming table name is EMP
UPDATE TABLE EMP
SET ENAME = SEX,
SEX = ENAME;
This will swap the values of the columns ename and sex not the column position.

Is this a right query? If it is what does it mean

I was given a query to explain. Could someone please explain it to me:
select j.ip_num from
jobs j, address a
where j.jobtype='C' and
a.sel_code(+)='H' and
j.ip_num=a.ip_num and
a.ip_num is null order by a.ip_num
That query selects every JOB.IP_NUM which doesn't have a matching ADDRESS record or where the matching ADDRESS record has a SEL_CODE not equal to 'H'.
The (+) is Oracle's old outer join syntax. It is the only OUTER JOIN syntax supported in versions of Oracle before 9i.
In this query we get one row for every row in EMP which matches a department, plus a row for the DEPTNO=40, which has no employees:
SQL> select d.dname
2 , e.ename
3 from dept d
4 , emp e
5 where d.deptno = e.deptno(+)
6 /
DNAME ENAME
-------------- ----------
ACCOUNTING SCHNEIDER
ACCOUNTING BOEHMER
ACCOUNTING KISHORE
RESEARCH ROBERTSON
RESEARCH KULASH
RESEARCH GASPAROTTO
RESEARCH RIGBY
RESEARCH CLARKE
SALES HALL
SALES CAVE
SALES SPENCER
SALES BILLINGTON
SALES PADFIELD
SALES VAN WIJK
SALES KESTELYN
SALES LIRA
OPERATIONS PSMITH
HOUSEKEEPING VERREYNNE
HOUSEKEEPING FEUERSTEIN
HOUSEKEEPING PODER
HOUSEKEEPING TRICHLER
COMMUNICATIONS
22 rows selected.
SQL>
Now, if we put an additional filter on the EMP table like this, we simply get one record for each Department, because only one record in EMP now matches:
SQL> select d.dname
2 , e.ename
3 from dept d
4 , emp e
5 where d.deptno = e.deptno(+)
6 and e.ename(+) = 'CAVE'
7 /
DNAME ENAME
-------------- ----------
ACCOUNTING
RESEARCH
SALES CAVE
OPERATIONS
HOUSEKEEPING
COMMUNICATIONS
6 rows selected.
SQL>
/
To convert this query into the ANSI SQL syntax we have to do this:
SQL> select d.dname
2 , e.ename
3 from dept d
4 left outer join emp e
5 on ( d.deptno = e.deptno
6 and e.ename = 'CAVE' )
7 /
DNAME ENAME
-------------- ----------
ACCOUNTING
RESEARCH
SALES CAVE
OPERATIONS
HOUSEKEEPING
COMMUNICATIONS
6 rows selected.
SQL>
Note that if we don't include the additonal clause in the JOIN but leave it in the WHERE clause we get a different result:
SQL> select d.dname
2 , e.ename
3 from dept d
4 left outer join emp e
5 on ( d.deptno = e.deptno )
6 where e.ename = 'CAVE'
7 /
DNAME ENAME
-------------- ----------
SALES CAVE
SQL>
This is the equivalent of omitting the (+) in the second old skool query.
The query is joining the 2 tables jobs, and address. These tables are joining on the field ip_num but you are looking for the records that exist in the jobs table but do not exist in the address table.
This is a LEFT OUTER JOIN. This query could also be written
SELECT j.ip_num
FROM jobs j
LEFT OUTER JOIN address a
ON j.ip_num=a.ip_num
WHERE j.jobtype='C' AND
a.sel_code(+)='H' AND
a.ip_num is null
ORDER BY a.ip_num
It might be useful to see a visual picture joins http://www.codinghorror.com/blog/2007/10/a-visual-explanation-of-sql-joins.html

Resources