mpinales
mpinales

Reputation: 29

How to get either a child or a parent record SQL

If I have a table that has an uniqueidentifier primary key called Id and there is a column called parentId, that points to another record in the same table that it may be linked to (column is null for parent records, child records have the Id of the parent record), how would I search and pull back a child record if one exists, and the parent record if there are no children? I am searching this table with data from another column that's not the primary key.

Upvotes: 0

Views: 49

Answers (1)

Code Novice
Code Novice

Reputation: 2398

I believe what you are looking for is Connect By Level.

https://asktom.oracle.com/pls/apex/f?p=100:11:0::::P11_QUESTION_ID:489772591421

I took the code from the above link and put it below. I hate dead links so this will keep the answer alive here on Stackoverflow.

I don't like providing examples that utilize DDL's as not everyone has the database privileges to create tables etc... The example below works with just plain SQL (Only uses DML). I like using With Blocks to form my tables in easy examples like this one (aka Common Table Expression - CTE).

WITH sample_data AS
(
    SELECT 'KING'   AS ENAMe, 7839 AS EMPNO, NULL AS MGR FROM DUAL UNION ALL
    SELECT 'JONES'  AS ENAMe, 7566 AS EMPNO, 7839 AS MGR FROM DUAL UNION ALL
    SELECT 'SCOTT'  AS ENAMe, 7788 AS EMPNO, 7566 AS MGR FROM DUAL UNION ALL
    SELECT 'ADAMS'  AS ENAMe, 7876 AS EMPNO, 7788 AS MGR FROM DUAL UNION ALL
    SELECT 'FORD'   AS ENAMe, 7902 AS EMPNO, 7566 AS MGR FROM DUAL UNION ALL
    SELECT 'SMITH'  AS ENAMe, 7369 AS EMPNO, 7902 AS MGR FROM DUAL UNION ALL
    SELECT 'BLAKE'  AS ENAMe, 7698 AS EMPNO, 7839 AS MGR FROM DUAL UNION ALL
    SELECT 'ALLEN'  AS ENAMe, 7499 AS EMPNO, 7698 AS MGR FROM DUAL UNION ALL
    SELECT 'WARD'   AS ENAMe, 7521 AS EMPNO, 7698 AS MGR FROM DUAL UNION ALL
    SELECT 'MARTIN' AS ENAMe, 7654 AS EMPNO, 7698 AS MGR FROM DUAL UNION ALL
    SELECT 'TURNER' AS ENAMe, 7844 AS EMPNO, 7698 AS MGR FROM DUAL UNION ALL
    SELECT 'JAMES'  AS ENAMe, 7900 AS EMPNO, 7698 AS MGR FROM DUAL UNION ALL
    SELECT 'CLARK'  AS ENAMe, 7782 AS EMPNO, 7839 AS MGR FROM DUAL UNION ALL
    SELECT 'MILLER' AS ENAMe, 7934 AS EMPNO, 7782 AS MGR FROM DUAL
)

SELECT lpad(' ',LEVEL*2,' ')||ename ename, empno, mgr
FROM sample_data
START WITH MGR IS NULL
CONNECT BY PRIOR EMPNO = MGR
;

Screenshot below to show it in action.

enter image description here

Upvotes: 1

Related Questions