sql >> Database >  >> RDS >> Oracle

Hiërarchische zoekopdracht - Records tellen die bij bovenliggende en onderliggende plaatsen horen

Hier is een optie:

Voorbeeldgegevens eerst:

SQL> with
  2  -- sample data
  3  place (id, parent_id, name, continent) as
  4    (select 11, null, 'USA'      , 'America' from dual union all
  5     select 22, 11  , 'New York' , 'America' from dual union all
  6     select 33, 22  , 'Manhattan', 'America' from dual union all
  7     select 44, null, 'Brasil'   , 'America' from dual union all
  8     select 55, 44  , 'Rio'      , 'America' from dual union all
  9     select 66, null, 'France'   , 'Europe'  from dual union all
 10     select 77, 66  , 'Paris'    , 'Europe'  from dual union all
 11     select 88, 66  , 'Nice'     , 'Europe'  from dual
 12    ),
 13  member (id, place_id) as
 14    (select  1, 22 from dual union all
 15     select  2, 77 from dual union all
 16     select  3, 33 from dual union all
 17     select  4, 22 from dual union all
 18     select  5, 55 from dual union all
 19     select  6, 55 from dual union all
 20     select  7, 88 from dual union all
 21     select  8, 88 from dual union all
 22     select  9, 88 from dual union all
 23     select 10, 22 from dual
 24    ),

Dan een paar CTE's (zie opmerkingen):

 25  -- naively, count members of leaf nodes
 26  naive as
 27    (select m.place_id, count(*) cnt
 28     from member m
 29     group by m.place_id
 30    ),
 31  -- set root parent node to each row
 32  cbr as
 33    (select connect_by_root p.id as tpid,
 34       p.id, p.parent_id, n.cnt
 35     from place p left join naive n on p.id = n.place_id
 36     connect by prior p.id = p.parent_id
 37     start with p.parent_id is null
 38     order by p.id
 39    ),
 40  -- how many members does each root node have?
 41  sumtpid as
 42    (select c.tpid, sum(c.cnt) cnt
 43     from cbr c
 44     group by c.tpid
 45    )
 46  -- join CBR + SUMTPID + PLACE for the final result
 47  select c.id, c.parent_id, nvl(c.cnt, s.cnt) member_count,
 48    p.name place_name,
 49    p.continent
 50  from cbr c join sumtpid s on s.tpid = c.tpid
 51             join place p on p.id = c.id
 52  order by c.id;

Wat resulteert in:

        ID  PARENT_ID MEMBER_COUNT PLACE_NAM CONTINE
---------- ---------- ------------ --------- -------
        11                       4 USA       America
        22         11            3 New York  America
        33         22            1 Manhattan America
        44                       2 Brasil    America
        55         44            2 Rio       America
        66                       4 France    Europe
        77         66            1 Paris     Europe
        88         66            3 Nice      Europe

8 rows selected.

SQL>


  1. update en voeg query's in die een impasse creëren

  2. MySQL:voer een basiszoekopdracht uit

  3. Waarom wordt hier de vraag 'WAARSCHUWINGEN TONEN' geplaatst? (JPA/Sluimerstand/MySQL)

  4. hoe de kolomwaarde slechts één keer wordt weergegeven als deze wordt herhaald en leeg is totdat een andere waarde in sql komt