Hierarchical query with join

Hi all
I want to reproduce the following query:
SQL> select to_char(level,'9') Lev,
first_name||' '||last_name Name, 
sys_connect_by_path((select first_name||' '||last_name from employees m where e.manager_id=m.employee_id),'/')Path,
(select department_name from departments d where d.department_id=e.department_id) Department 
from employees e 
start with employee_id=100 
connect by manager_id=prior employee_id order siblings by 4,3,2;

LE NAME           PATH                      DEPARTMENT
-- -------------------- ------------------------------ ---------------
 1 Steven King          /                      Executive
 2 Lex De Haan          //Steven King                 Executive
 3 Alexander Hunold     //Steven King/Lex De Haan      IT
 4 Bruce Ernst          //Steven King/Lex De Haan/Alex IT
               ander Hunold

-- QUERY TRUNCATED --

 3 Sarah Bell          //Steven King/Shanta Vollman   Shipping
 3 Stephen Stiles     //Steven King/Shanta Vollman   Shipping
 3 Vance Jones          //Steven King/Shanta Vollman   Shipping

107 rows selected.
with a JOIN query. This query uses the example of the HR diagram and displays the names of the employees with their managers and departments using join instead of correlated query. So far, I got:
SQL> select first_name|| ' '||last_name Name,
Manager,Department from employees e,
(select first_name||' '||last_name Manager,employee_id,first_name first from employees) m ,
(select department_name Department,department_id from departments) d 
where e.manager_id=m.employee_id  and e.department_id=d.department_id;

NAME               MANAGER            DEPARTMENT
-------------------- -------------------- --------------------
Lex De Haan          Steven King       Executive
Neena Kochhar          Steven King       Executive
Eleni Zlotkey          Steven King       Sales
Gerald Cambrault     Steven King       Sales
Alberto Errazuriz    Steven King       Sales
Karen Partners          Steven King       Sales

-- QUERY TRUNCATED --

John Russell          Steven King       Sales
Kevin Mourgos          Steven King       Shipping
Shanta Vollman          Steven King       Shipping
Payam Kaufling          Steven King       Shipping
Adam Fripp          Steven King       Shipping
Pat Fay           Michael Hartstein       Marketing
William Gietz          Shelley Higgins       Accounting

105 rows selected.

SQL> select first_name|| ' '||last_name Name,
Manager,Department from employees e,
(select first_name||' '||last_name Manager,employee_id,first_name first from employees) m ,
(select department_name Department,department_id from departments) d where e.manager_id=m.employee_id  and e.department_id=d.department_id 
start with e.employee_id=100 connect by e.manager_id=prior e.employee_id;

no rows selected

SQL> 
But the above query returns lines until I have slides BEGIN WITH CONNECT BY clause, which returns nothing. What is the problem with the START WITH CONNECT BY clause from the second query?

Best regards
TA.

Published by: Valerie good-natured April 18, 2011 02:54

Employee no. 100 has no manager_id, so you need an outer join:

select first_name|| ' '||last_name Name,
Manager,Department from employees e,
(select first_name||' '||last_name Manager,employee_id,first_name first from employees) m ,
(select department_name Department,department_id from departments) d where
e.manager_id=m.employee_id (+)
and e.department_id=d.department_id (+)
start with e.employee_id=100 connect by e.manager_id=prior e.employee_id;

Hope this helps,
Tony

Tags: Database

Similar Questions

  • Internal XML to the query with join

    I have a CF page that reads an XML file in a query using < cffile > XMLParse and QueryAddrow.

    I then do a QoQ on the result and voila! I have my page.  I hide the query for 8 hours and the XML file is only reread this cache expires.  It works well.

    My problem now is that the file contains data from three tables of database instead of one, so I need to make an inner join on the tables.  But I can't do a t/t with an inner join.

    Does anyone know a way for me to do this?

    Oh, didn't know that.  How about interweaving of QofQ?  Join Query1 and Query2 requests in a new query, then join for 3 statement?

  • Rewrite the query with joins, and group by

    Hello

    It's an interview question.

    Table names: bookshelf_checkout
    virtual library

    And the join condition between these two tables is title

    We need to rewrite under request without using the join condition and group by clause?

    SELECT b.title,max(bc.returned_date - bc.checkout_date) "Most Days Out"
               FROM bookshelf_checkout bc,bookshelf b
               WHERE bc.title(+)=b.title
               GROUP BY b.title;
    When I was in College, I read most of SELECT statements can be replaced by operations base SQL (DEFINE the OPERATORS). Now, I am rewriting the query with SET operators, but not able to get the exact result.

    Kindly help me on this.

    Thank you
    Suri

    Something like that?

      1  WITH books AS (
      2  SELECT 'title 1' title FROM dual UNION ALL
      3  SELECT 'title 2' FROM dual UNION ALL
      4  SELECT 'title 3' FROM dual ),
      5  bookshelf AS (
      6  SELECT 'title 1' title, DATE '2012-05-01' checkout_date, DATE '2012-05-15' returned_date FROM dual UNION ALL
      7  SELECT 'title 1' title, DATE '2012-05-16' checkout_date, DATE '2012-05-20' returned_date FROM dual UNION ALL
      8  SELECT 'title 2' title, DATE '2012-04-01' checkout_date, DATE '2012-05-15' returned_date FROM dual )
      9  SELECT bs.title, MAX(bs.returned_date - bs.checkout_date) OVER (PARTITION BY title) FROM bookshelf bs
     10  UNION
     11  (SELECT b.title, NULL FROM books b
     12  MINUS
     13* SELECT bs.title, NULL FROM bookshelf bs)
    SQL> /
    
    TITLE   MAX(BS.RETURNED_DATE-BS.CHECKOUT_DATE)OVER(PARTITIONBYTITLE)
    ------- ------------------------------------------------------------
    title 1                                                           14
    title 2                                                           44
    title 3
    

    Lukasz

  • Query with join optimization research and details of the extra column

    I have the following SQL used for a report that comes out some stats (with some research of names). There is a good chance it is probably possible to optimize with better SQL, but I also hope to add an additional column, which I'm not sure.

    I want the extra column at one percent, which is total % of the lines of the value of the units, for the combination of category/group.

    Oracle SQL is v11.2.0

    Here's the SQL code, as it is currently:

    select a.date_adjusted, 
           a.task_name,
           sum(case when a.units_adjusted is not null then a.units_adjusted else a.units_original end) Units, 
           b.group_name, 
           b.category_name
    from   actuals_intake a
    left join
    -- lookups to obtain group and category names from their ID's in the groupings table
           (select c.task_id, 
                   d.group_name, 
                   e.category_name, 
                   c.business_unit_id
            from   task_groupings c,
                   task_groups d,
                   task_categories e
            where  c.group_id = d.id
            and    c.business_unit_id = d.business_unit_id
            and    c.category_id = e.id
            and    c.business_unit_id = e.business_unit_id
    ) b
    on    a.task_id = b.task_id
    and   a.business_unit_id = b.business_unit_id
    where a.business_unit_id = :P10_SELECT_BUSINESS_UNIT
    and   a.date_adjusted between to_date(:P10_DATE_START, 'dd-mon-yyyy') and to_date(:P10_DATE_END, 'dd-mon-yyyy')
    group by a.date_adjusted, a.task_name, b.group_name, b.category_name
    order by a.date_adjusted, b.category_name, b.group_name
     

    This will set up the tables and data:

    CREATE TABLE ACTUALS_INTAKE (
    ID NUMBER,
    DATE_ORIGINAL DATE,
    TASK_NAME VARCHAR2(500 CHAR),
    TASK_ID NUMBER,
    UNITS_ORIGINAL NUMBER,
    BUSINESS_UNIT_ID NUMBER,
    SUB_UNIT_ID NUMBER,
    DATE_ADJUSTED DATE,
    UNITS_ADJUSTED NUMBER
    );
    CREATE TABLE TASK_CATEGORIES (
    ID NUMBER, 
    CATEGORY_NAME VARCHAR2(100 CHAR), 
    BUSINESS_UNIT_ID NUMBER
    );
    CREATE TABLE TASK_GROUPS (
    ID NUMBER, 
    GROUP_NAME VARCHAR2(100 CHAR), 
    BUSINESS_UNIT_ID NUMBER
    );
    CREATE TABLE TASK_GROUPINGS (
    TASK_ID NUMBER, 
    GROUP_ID NUMBER, 
    CATEGORY_ID NUMBER, 
    BUSINESS_UNIT_ID NUMBER
    );
     
     
    INSERT ALL
    INTO ACTUALS_INTAKE (ID, DATE_ORIGINAL, TASK_NAME, TASK_ID, UNITS_ORIGINAL, BUSINESS_UNIT_ID, SUB_UNIT_ID, DATE_ADJUSTED, UNITS_ADJUSTED)
    VALUES (1, '03/15/2014', 'Task One', 1, 200, 10, null, '03/15/2014', null)
    INTO ACTUALS_INTAKE (ID, DATE_ORIGINAL, TASK_NAME, TASK_ID, UNITS_ORIGINAL, BUSINESS_UNIT_ID, SUB_UNIT_ID, DATE_ADJUSTED, UNITS_ADJUSTED)
    VALUES (2, '03/15/2014', 'Task Two', 2, 30, 10, null, '03/15/2014', null)
    INTO ACTUALS_INTAKE (ID, DATE_ORIGINAL, TASK_NAME, TASK_ID, UNITS_ORIGINAL, BUSINESS_UNIT_ID, SUB_UNIT_ID, DATE_ADJUSTED, UNITS_ADJUSTED)
    VALUES (3, '03/15/2014', 'Task Three', 3, 650, 10, null, '03/15/2014', null)
    INTO ACTUALS_INTAKE (ID, DATE_ORIGINAL, TASK_NAME, TASK_ID, UNITS_ORIGINAL, BUSINESS_UNIT_ID, SUB_UNIT_ID, DATE_ADJUSTED, UNITS_ADJUSTED)
    VALUES (4, '03/15/2014', 'Task Four', 4, 340, 10, null, '03/15/2014', null)
    INTO ACTUALS_INTAKE (ID, DATE_ORIGINAL, TASK_NAME, TASK_ID, UNITS_ORIGINAL, BUSINESS_UNIT_ID, SUB_UNIT_ID, DATE_ADJUSTED, UNITS_ADJUSTED)
    VALUES (5, '03/14/2014', 'Task Four', 4, 60, 10, null, '03/15/2014', null)
    INTO ACTUALS_INTAKE (ID, DATE_ORIGINAL, TASK_NAME, TASK_ID, UNITS_ORIGINAL, BUSINESS_UNIT_ID, SUB_UNIT_ID, DATE_ADJUSTED, UNITS_ADJUSTED)
    VALUES (6, '03/15/2014', 'Task Five', 5, 15, 10, null, '03/15/2014', null)
    INTO ACTUALS_INTAKE (ID, DATE_ORIGINAL, TASK_NAME, TASK_ID, UNITS_ORIGINAL, BUSINESS_UNIT_ID, SUB_UNIT_ID, DATE_ADJUSTED, UNITS_ADJUSTED)
    VALUES (7, '03/15/2014', 'Task Six', 6, 40, 10, null, '03/15/2014', null)
    SELECT 1 FROM DUAL;
     
     
    INSERT ALL
    INTO TASK_GROUPS (ID, GROUP_NAME, BUSINESS_UNIT_ID)
    VALUES (1, 'Group One', 10)
    INTO TASK_GROUPS (ID, GROUP_NAME, BUSINESS_UNIT_ID)
    VALUES (2, 'Group Two', 10)
    INTO TASK_GROUPS (ID, GROUP_NAME, BUSINESS_UNIT_ID)
    VALUES (3, 'Group Three', 10)
    select 1 from dual;
    
     
    INSERT ALL
    INTO TASK_CATEGORIES (ID, CATEGORY_NAME, BUSINESS_UNIT_ID)
    VALUES (1, 'Category A', 10)
    INTO TASK_CATEGORIES (ID, CATEGORY_NAME, BUSINESS_UNIT_ID)
    VALUES (2, 'Category A', 10)
    INTO TASK_CATEGORIES (ID, CATEGORY_NAME, BUSINESS_UNIT_ID)
    VALUES (3, 'Category B', 10)
    select 1 from dual;
    
     
    INSERT ALL
    INTO TASK_GROUPINGS (TASK_ID, GROUP_ID, CATEGORY_ID, BUSINESS_UNIT_ID)
    VALUES (1, 1, 1, 10)
    INTO TASK_GROUPINGS (TASK_ID, GROUP_ID, CATEGORY_ID, BUSINESS_UNIT_ID)
    VALUES (2, 1, 1, 10)
    INTO TASK_GROUPINGS (TASK_ID, GROUP_ID, CATEGORY_ID, BUSINESS_UNIT_ID)
    VALUES (3, 2, 2, 10)
    INTO TASK_GROUPINGS (TASK_ID, GROUP_ID, CATEGORY_ID, BUSINESS_UNIT_ID)
    VALUES (4, 2, 3, 10)
    INTO TASK_GROUPINGS (TASK_ID, GROUP_ID, CATEGORY_ID, BUSINESS_UNIT_ID)
    VALUES (5, 3, 3, 10)
    INTO TASK_GROUPINGS (TASK_ID, GROUP_ID, CATEGORY_ID, BUSINESS_UNIT_ID)
    VALUES (6, 3, 3, 10)
    select 1 from dual;
     

    Results will look like this. The last column is what I want the extra column to look like:

    Date_Adjusted TaskName Units of GroupName Category_Name Units %
    15/03/2014A task200Group 1Category A87
    15/03/2014Task 230Group 1Category A13
    15/03/2014Task 3650Group twoCategory A100
    15/03/2014Task 515Group threeCategory B27
    15/03/2014Task 640Group threeCategory B73
    15/03/2014Task 4400Group twoCategory B100

    Hope all that makes sense... Anyone able to help me do this effectively?

    Hello

    Use the analytical RATIO_TO_REPORT function to calculate the % of units column.

    If you're serious about performance, please refer to the Forum:

    Re: 3. how to improve the performance of my query? / My query is slow.

    Do you really need an outer join?  Inner joins are faster.  With the given sample data, they produce the same results.

    COALESCE may be a little faster than the CASE.

    Try this:

    WITH got_units AS

    (

    SELECT a.date_adjusted,

    a.Task_Name,

    sum of units (COALESCE (a.units_adjusted, a.units_original));

    b.group_name,

    b.category_name

    of actuals_intake one

    the left join - or just JOINED

    -research for the group names and category of their ID in the table of groupings

    (select c.task_id,

    d.group_name,

    e.category_name,

    c.business_unit_id

    of task_groupings c,.

    task_groups d,

    e task_categories

    where d.id = c.group_id

    and c.business_unit_id = d.business_unit_id

    and c.category_id = e.id

    and c.business_unit_id = e.business_unit_id

    ) b

    On a.task_id = b.task_id

    and a.business_unit_id = b.business_unit_id

    -where a.business_unit_id =: P10_SELECT_BUSINESS_UNIT - if necessary

    - and a.date_adjusted between to_date (: P10_DATE_START, 'Mon-dd-yyyy') and to_date (: P10_DATE_END, ' mon-dd-yyyy "")

    Group of a.date_adjusted, a.task_name, b.group_name, b.category_name

    )

    SELECT u.*

    ROUND (100 * RATIO_TO_REPORT (units) OVER (PARTITION BY groupname)

    category_name

    )

    ) AS units_pct

    OF got_units u

    ORDER BY date_adjusted, category_name, GroupName

    ;

    Thanks for the display of the data of the sample; It is very useful.  Don't try to insert strings, for example, March 15, 2014", in DATE columns.  TO_DATE allows to convert strings to DATEs.

  • Update query with join statement

    Hi guys, would check how to write a query to update with the inner join statement? The case is like this, I need to update PRD_ID on TBL A as below, based on the information of lookup table. The keys are based on the A03 column to the table time to condition only select records in LOOKUP_TBL where PRD_ID = 110001 then update to TBL_A for those who match the data and FIX_FLT = 1

    I have an update query and it works in SQL SERVER but not in ORACLE

    Update a PRD_ID = B.PRD_ID set

    Inner TBL_A A join B LOOKUP_TBL

    On A.A03 = B.A03

    AND A.FIX_FLT = 1 AND B.PRD_ID = '110001';

    TBL_A

    PRD_IDA03FIX_FLTTXNDATE
    1A11123/10/2010
    1A21110/24/2010
    1A33210/25/2010
    1A43210/26/2010
    1A53127/10/2010

    LOOKUP_TBL

    PRD_IDA03NOTE
    110001A1NULL VALUE
    110001A2NULL VALUE
    110005A3NULL VALUE
    110005A4NULL VALUE
    110001A5NULL VALUE

    You can write updates like this in Oracle.  It's called updatable join views.  Something like this:

    Update
    (select a.prd_id a_prd_id
    b.prd_id b_prd_id
    Inner TBL_A A join B LOOKUP_TBL
    On A.A03 = B.A03
    AND A.FIX_FLT = 1 AND B.PRD_ID = '110001'
    )
    Set a_prd_id = b_prd_id;

    But you must have the constraints appropriate in place, otherwise you will get the error "key preserved table.

  • Hierarchical query with several parents and children without parents

    Hi all,

    I have a problem of follow-up:

    1, parent_1,.

    2, child_1, 1

    3, child_2, 1

    4, grandchild_1, 2

    5, parent_2,.

    6, child_3, 5

    7, child_0,.

    In this case, I can have multiple parents, and I also have children who do not have parents. Can someone help me solve this problem

    Concerning

    Hello

    So, if a node has itself or 0 as its parent_id, it's the same as with the NULL value?

    In this case, include all these possibilities in the START WITH clause:

    SELECT DLI

    , LPAD (' ' ')

    , (LEVEL - 1) * 3

    , ' '

    ) || descr AS descr

    parent_id

    T

    START WITH NVL (parent_id, 0) (0, DLI)

    CONNECT BY parent_id = PRIOR DLI

    AND idd <> parent_id

    ;

  • transformation of query using joins

    My current query works perfectly.

    SELECT so.* FROM shipping_order so, WHERE (so.submitter = 20) OR (so.requestor_id IN (SELECT poc.objid FROM point_of_contact WHERE poc.ain = 20 poc)) OR so.objid IN (SELECT ats.shipping_order_id from ac_to_so ats WHERE (ats.access_control_id IN (objid selectac.) Of access_control ac WHERE ac.ain = 20 GOLD ac.group IN ("buyers", "managers")))

    But when I try to create it using the join instructions examples I do not get the correct results or no results indeed.

    Here's the query with joins.

    SELECT so.* FROM shipping_order so INNER JOIN point_of_contact ON (so.requestor_id = poc.objid AND poc.ain = 20) INNER JOIN ac_to_so ats WE (so.objid = ats.shipping_order_id) INNER JOIN access_control ac WE (ats.access_control_id = ac.objid AND (ac.group ("buyers", "managers") IN GOLD ac.ain = 20)) WHERE (so.submitter = 20)

    Any ideas on what I am doing wrong. I tried both outer joins and received no results either.

    TIA.

    Published by: user9522282 on March 11, 2009 06:27 fixed typo
    select s.*
      from shipping_order s
      left outer
      join ac_to_so a
        on (s.objid = a.shipping_order_id)
      left outer
      join access_control ac
        on (a.access_control_id = ac.objid)
      join point_of_contact poc
        on (poc.objid = s.requestor_id)
     where s.submitter = 20
        or poc.ain = 20
        or ac.ain = 20
        or ac.user_group in ('buyers', 'managers')
    
  • Help with hierarchical query

    I'm trying to parse each string inside of individual characters. For this, I used the link by the hierarchical query clause. I am not able to use connect by correctly. Here is my example.

    with the CBC as)

    Select 1: the nurse, 'abc' double union all Str

    Select 2: the nurse, '123' Str of all union double

    Select 3: the nurse, "pqr xyz" dual union all Str

    Select option 4: the nurse, 'john doe' double Str

    )

    Select the level, homobasidiomycetes, substr(s.str,level,1) as chr

    s of the CBC

    connect nocycle level < = length (homobasidiomycetes)

    /

    The above query returns 3 028 lines when I want that 21. Adding a distinct to select, it's what I want.

    with the CBC as)

    Select 1: the nurse, 'abc' double union all Str

    Select 2: the nurse, '123' Str of all union double

    Select 3: the nurse, "pqr xyz" dual union all Str

    Select option 4: the nurse, 'john doe' double Str

    )

    Select distinct level, homobasidiomycetes, substr(s.str,level,1) as chr

    s of the CBC

    connect nocycle level < = length (homobasidiomycetes)

    order by str, level

    /

    For a large data set I could end up with several million rows before the separate would lead. So, how can I restrict the connection by clause to go within each line.

    Assuming that the AI is the primary key, you could do this:

    with src as (
      select 1 as rn, 'abc' as str from dual union all
      select 2 as rn, '123' as str from dual union all
      select 3 as rn, 'pqr xyz' as str from dual union all
      select 4 as rn, 'john doe' as str from dual
    )
    select level,
          s.str,
          substr(s.str,level,1) as chr
    from src s
    connect by level <= length(s.str)
              and prior rn = rn
              and prior dbms_random.value is not null;
    

    See DBMS_RANDOM.value in a hierarchical solution for string to table? for an exchange of views around the case.

  • Problems with views based on a hierarchical query

    Datamodeler 3.1.3.706 (SQL Dev 3.2.10.09):

    When you create a view that uses a hierarchical query, the query designer encounter various difficulties:

    When pasting in the SQL code, if the notice is registered without first clicking the schema update button, the object in the entity-relationship diagram view provides a faithful representation of the view without errors, but when the reopening of the view, the code is missing.

    Simple example with the classic emp table:
    SELECT level lev
          , emp.*
       FROM emp
      CONNECT BY prior empno = mgr
      START WITH mgr        IS NULL
    If you press the schema update button to refresh the display. He mangles connect it by the clause and the view gets marked with a warning/error icon in the diagram of the relationships, but the now decomposed code remains available on reopening of the query designer.

    Same code as above after having clicked on the button of update of schema:
     SELECT Level lev
    , emp.*
       FROM emp
      CONNECT BY
    Other issues are met if the query contains a column CONNECT_BY_ % nickname hierarchical:
    SELECT level
          , emp.*
          , connect_by_root emp.ename root_ename
       FROM emp
      CONNECT BY prior empno = mgr
      START WITH mgr        IS NULL;
    In this case, paste in the code and clicking Update schema button or the OK button translates into a "unexpected Token' error analysis.

    These problems are encountered with the logic model and the relational.

    Is this a known issue? I searched this forum but have not found any references to this.

    Thank you

    Sentinel

    Hi, Sentinel,

    I logged a bug for this.
    You can try 3.3 DM treat it better first problem, analysis of connect_by_root operator will pass if you do not alias.

    Philippe

  • How to use order by with hierarchical query

    I have a hierarchical query basically he brings an organization chart. We start with the Manager id, get everything that employees of the person. If the employee is also a Manager I want to get the employees of that person and turn them right after that person. I don't bother with the entire query but relevant part is:
           START WITH em.mgr_id = pi_mgr_id
          CONNECT BY nocycle PRIOR em.emp_id = em.mgr_id;
    Where pi_mgr_id is a parameter passed to the procedure and the em is the alias of the emp_mgr_relationship table that contains emp_id and mgr_id. It works very well. What I want now is for employees who work for the same Manager appear in the order of name. The table that contains the names of the employees is an alias as pe and the name column is called name1. I added the following:
           START WITH em.mgr_id = pi_mgr_id
          CONNECT BY nocycle PRIOR em.emp_id = em.mgr_id
            order by pe.name1;
    But what to put the entire list in the order of name. What I want is for the employees who work for the same manager be in name order. We're going to the manager that I want to the body is named Frank. I want to get it
    EMP_NAME    MGR_NAME
    Allen       Frank
    Beth        Frank
    Alex        Beth
    Charles     Beth
    Ed          Beth
    Dean        Frank
    George      Frank
    Benny       George
    David       George
    Sam         George
    Dan         Sam
    Harry       Sam
    John        Sam
    Terry       George
    James       Frank
    Ken         Frank
    Mike        Ken
    Warren      Ken
    How can I get the list in order?

    Published by: kendenny on July 28, 2010 07:31

    Make use of the ORDER of Friars and SŒURS clause in the hierarchical queries to define the order of child columns.

    START WITH em.mgr_id = pi_mgr_id
          CONNECT BY nocycle PRIOR em.emp_id = em.mgr_id
            *order siblings by name1;*
    
  • Support for hierarchical query

    Hi all

    I must be tired and can't think clearly, so I am a little confused the following query.

    The environment is Oracle 9i:

    Oracle9i Enterprise Edition Release 9.2.0.8.0 - 64 bit Production

    PL/SQL Release 9.2.0.8.0 - Production

    CORE Production 9.2.0.8.0

    AMT for HP - UX: 9.2.0.8.0 - Production Version

    NLSRTL Version 9.2.0.8.0 - Production

    Suppose I have the following data:

    with mydata as

    (

    Select the code 1, code_high, null, 'John' cname 'Smith' csurname, 'X' union resp. double all the

    Select 2 code, 1 code_high, cname 'Bill', 'White' csurname, RESP null in union double all the

    Select 3 code, code_high 2, 'Fred' cname 'Reed' csurname, 'X' union resp. double all the

    Select 4 code, code_high, null, 'Tim' cname 'Hackman' csurname, 'X' union resp. double all the

    Select code 5, code_high 4, 'John', 'Reed' cname csurname resp null in union double all the

    Select 6 code, code_high 5, cname 'Bill', 'Hakcman' csurname, 'X' union resp. double all the

    Select the code 7, code_high 6, cname 'Fred' csurname 'White', null union resp. double all the

    Select code 8, code_high 7, 'Bill' cname 'Smith' csurname, resp. union null double all the

    Select 9 code, code_high 8, cname "Tom", "Reed" csurname, null double RESP

    )

    Select *.

    of mydata;

    CODE CODE_HIGH CNAME CSURNAME RESP

    ---------- ---------- ----- -------- ----

    John Smith 1 X

    2 1 bill White

    3 2 Fred Reed X

    4 Tim Hackman X

    5 4 John Reed

    6 5 bill Hakcman X

    7 6 Fred white

    8 7 bill Smith

    9 8 Tom Reed

    It is a hierarchical query where code_high represents the father.

    I need to find in the hierarchy of higher level responsible for each code.

    Suppose I want to find in the hierarchy, one with resp = 'X '.

    Run the following query I find for the code = 9

    Select phone, cname, csurname code

    of mydata

    When resp = 'X '.

    and rownum = 1

    Connect prior code_high = code

    start with code = 9;

    CODE CNAME CSURNAME

    ---------- ----- --------

    Bill 6 Hakcman

    Is there a way to get the full list with the loaded correspondents.

    The expected results are:

    CODE CODE_HIGH CNAME CSURNAME RESP. RESP_CODE RESP_NAME RESP_SURNAME

    ---------- ---------- ----- -------- ---- --------- --------- ------------

    1 John Smith John Smith 1 X

    2 1 bill White 1 John Smith

    3 2 Fred Reed X 3 Fred Reed

    Tim Hackman 4 X 4 Tim Hackman

    5 4 John Smith 4 Tim Hackman

    6 5 bill Hakcman Bill Hakcman 6 X

    7 6 Fred White 6 Bill Hakcman

    8 7 bill Smith 6 Bill Hakcman

    9 8 Tom Reed 6 Bill Hakcman

    Kind regards.

    Alberto

    Hi, Alberto.

    I know that you are using Oracle 9; That's why I mentioned that you would have to use a substitute for CONNECT_BY_ROOT.  Before I could show how, I saw the solution of the Padders, which is probably simpler and more efficient for this work.  Padders used REGEXP_SUBSTR, which is not available in Oracle 9, but you can use SUBSTR and INSTR instead.

    Here is the solution of the Padders for Orcle 9:

    WITH got_resp_path AS

    (

    SELECT m.*

    RTRIM (SYS_CONNECT_BY_PATH (CASE

    WHEN resp = 'X '.

    THEN the code

    END

    , ' '

    )

    ) AS resp_path

    OF mydata m

    START WITH code_high IS NULL

    CONNECT BY code_high = code PRIOR

    )

    C. SELECT

    r.code AS resp_code

    r.cname AS resp_name

    r.csurname AS resp_surname

    OF got_resp_path c

    JOIN mydata r ON r.code = TO_NUMBER (SUBSTR (c.resp_path

    INSTR (c.resp_path

    , ' '

    -1

    )

    )

    )

    ORDER BY c.code

    ;

    I agree that what you posted in your last post is not very satisfactory.  Rather than make a CONNECT a separate query for each column of resp_ you want to view, you can modify it to get only the unique code and then use it in a join, as Padders, to get all the other columns you need.

  • Hierarchical data, how to aggregate over levels in hierarchical query?

    Hello

    I hope someone can help me.

    I held in a data table ("" what part was built in what other part of when when? "')
    ID parent_id build_in build_out
    1 NULL NULL NULL
    2/1 2010 2012
    3 2 2011 2013
    4 2 2013 NULL

    What are the parts is stored in a separate table.

    Now I want to know when when which part was built in the first level, in the example, I want to know that
    1 was simply a part of 1
    2 was part of 1 between 2010 and 2012
    3 was part of 1 between 2011 and 2012
    4 has never been a part of 1

    I tried several approaches - if there is a fixed number of levels between the types, I am interested I can do using joins and more/less (similarly as some nvl). Unfortunately this is not always the case (some parts appear on several levels).
    If I'm only interested in the parts that are never deleted, I can get by using a style of connect request and get the current configuration. But I can't seem to understand the time connecting part to the high level in such a query, or even filtering absurd combinations (like "4 in 1" in the example above). I could deal with the data recovered outside the database, but I prefer not.

    Is there a way to obtain the hierarchical data with an aggregate (min, max) for all levels?

    What version of Oracle you are on?

    In 11.2.x, you can use the recursive subquery factoring. Something like

    with t (id, parent_id, build_in, build_out) as (
    select 1, null, null, null from dual union all
    select 2, 1, 2010, 2012 from dual union all
    select 3, 2, 2011, 2013 from dual union all
    select 4, 2, 2013, null from dual
    )
    , c1 (root_id, id, parent_id, build_in, build_out) as (
    select id, id, parent_id, 0, 9999
    from t
    where parent_id is null
    union all
    select root_id, t.id, t.parent_id
    , greatest(nvl(t.build_in,0), nvl(b.build_in,0))
    , least(nvl(t.build_out,9999), nvl(b.build_out,9999))
    from c1 b, t
    where b.id = t.parent_id
    )
    select * from c1
    where build_in < build_out
    ;
    ROOT_ID ID    PARENT_ID  BUILD_IN  BUILD_OUT
    ------- ----- ---------- --------- ----------
    1       1                0         9999
    1       2     1          2010      2012
    1       3     2          2011      2012      
    

    With a hierarchical query by using the syntax connection, you could do something like

    select * from (
    select connect_by_root id as root, id
    , greatest(nvl(build_in,0), nvl(prior build_in,0)) as max_in, least(nvl(build_out,9999), nvl(prior build_out,9999)) as min_out
    from t
    start with parent_id is null
    connect by parent_id = prior id
    )
    where max_in < min_out
    ;
    

    but it is not powerful enough. This version compares the dates between a current and previous levels, but the recursive subquery is to compare the dates in the current level for the winners of the comparisons to the previous level. Not sure if it's an important distinction for your needs, however.

    If you are on 11.2 I advise to use the recursive subquery factoring. If this isn't the case, you can try the link by version.

    Kind regards
    Bob

  • A hierarchical query help

    I have two tables:

    The FOLDERS where the areas concerned are: folderId, parentFolderId, folderQuota
    and DOCUMENTS where the areas concerned are: folderId, size

    FILES is hierarchical - parentFolderId of the file of the child has the folderId of the parent value
    folderQuota the value null (undefined quota)


    Now, I need to run a query with the following recursive logic

    < i > function calcQuota (folderIdpar, isFirstpar) {}

    If (not isFirstpar) and (folderQuota of the folder with folderIdpar is not null) return folderQuota;
    Returns the size of all documents where folderId = folderIdpar + calcQuota (folderId of all children, false);

    } < /i >

    (I hope the pseudo-code is understandable - the query is executed as < i > calcQuota (originalFolderId, true) < /i >).

    Now, my question is if I can accomplish this with a single hierarchical query, or if I should implement as a recursive procedure stored.

    Thank you!

    P.S. I use Oracle XE (10g)

    Hello

    If you want to ignore the quotas at the level = 1:

    WITH     tree     AS
    (
         SELECT     folder_id
         ,     CASE
                   WHEN  LEVEL > 1
                   THEN  quota
              END                         AS effective_quota
         FROM     folders          f
         START WITH     folder_id          = :start_folder_id
         CONNECT BY     parent_folder_id     = PRIOR folder_id
              AND     (   PRIOR quota          IS NULL
                   OR  LEVEL          = 2
                   )
    )
    SELECT     :start_folder_id
    ,     SUM ( NVL ( t.effective_quota
                , d.document_size
                )
             )          AS total_size
    FROM     tree               t
    LEFT OUTER JOIN documents     d     ON     t.folder_id          = d.folder_id
                             AND     t.effective_quota     IS NULL
    ;
    
  • How to convert the hierarchical query of SQL Server (CTE) to Oracle?

    How to convert the hierarchical query of SQL Server (CTE) to Oracle?

    WITH cte (col1, col2) AS
    (
    SELECT col1, col2
    FROM dbo. [tb1]
    WHERE col1 = 12
    UNION ALL
    SELECT c.col1, c.col2
    FROM dbo. [tb1] AS c INNER JOIN cte AS p ON c.col2 = p.col1
    )
    DELETE one
    FROM dbo. [tb1] AS an INNER JOIN b cte
    ON a.col1 = b.col1

    Hello
    Something like this maybe:

    DELETE FROM dbo.tb1 a
     WHERE EXISTS (
      SELECT 1
        FROM dbo.tb1 b
      WHERE a.co11 = b.col1
          AND a.col2 = b.col2
       START WITH b.col1 = 12
      CONNECT BY b.col2 = PRIOR b.col1)
    

    Although you need to do here is to check that CONNECT it BY SELECT, returns records you wait first, then the DELETION should work too.

  • Query on hierarchical query in interactive report!

    Hello

    In Apex Oracle 5.1, I tried to use an interactive report to view details of employee based on a hierarchy. I used the query to display data below:

    SELECT last_name, employe_id, manager_id, LEVEL

    Employees

    START WITH employee_id = 100

    CONNECT BY PRIOR employee_id = manager_id

    Brothers and SŒURS of ORDER BY last_name;

    The output was as below:

    LAST_NAME EMPLOYEE_ID MANAGER_ID LEVEL

    ------------------------- ----------- ---------- ----------

    King                                100                                                       1

    Cambrault                        148                                 100                 2

    Bates                              172                                 148                 3

    Bloom                             169                                  148                3

    Fox                                 170                                  148                3

    Kumar                             173                                  148                3

    Ozer                                168                                  148               3

    Smith                               171                                  148              3

    De Haan                           102                                   100             2

    Hunold                              103                                   102             3

    Austin                               105                                   103             4

    Ernst                                 104                                   103             4

    Lorentz                              107                                   103             4

    Pataballa                           106                                    103            4

    Errazuriz                           147                                   100              2

    Ande                                 166                                    147             3

    Banda                               167                                     147             3

    ...

    Now, I would like to display data based on the connection of employees.

    For example (based on above request): If an employee named - Cambrault is the login, only employees under him (Bates, Bloom, Fox, Kumar, Smith, Ozer) and its own contact information should appear in the report.

    Please advise.

    Kind regards

    mebu

    Mebu wrote:

    I used a hierarchical query. But based on Login, I want to display only members under him.

    For example: If Cambrault LOGIN, only employees under him (Bates, Bloom, Fox, Kumar, Smith, Ozer) and its own coordinates must display in Oracle Apex.

    SELECT last_name, employe_id, manager_id, LEVEL

    Employees

    START WITH employee_id = 100

    CONNECT BY PRIOR employee_id = manager_id

    Brothers and SŒURS of ORDER BY last_name;

    See what/when/where? How to get the answers from the forum

    Describe the requirements clearly and completely, using the APEX, Oracle and terminology of web standard.

Maybe you are looking for