sql >> Database teknologi >  >> RDS >> Oracle

Rekursiv Indsæt ved hjælp af connect by-sætning

Hvis alle bladknuder er i samme højde (her lvl=4), kan du skrive en simpel CONNECT BY-forespørgsel med en ROLLUP:

SQL> SELECT lvl0,
  2         regexp_substr(path, '[^/]+', 1, 2) lvl1,
  3         regexp_substr(path, '[^/]+', 1, 3) lvl2,
  4         SUM(VALUE) sum_value
  5    FROM (SELECT sys_connect_by_path(t.element, '/') path,
  6                 connect_by_root(t.element) lvl0,
  7                 t.element, d.VALUE, LEVEL lvl
  8             FROM tree t
  9             LEFT JOIN DATA d ON d.element = t.element
 10            START WITH t.PARENT IS NULL
 11           CONNECT BY t.PARENT = PRIOR t.element)
 12   WHERE VALUE IS NOT NULL
 13     AND lvl = 4
 14   GROUP BY lvl0, ROLLUP(regexp_substr(path, '[^/]+', 1, 2),
 15                         regexp_substr(path, '[^/]+', 1, 3));

LVL0 LVL1  LVL2   SUM_VALUE
---- ----- ----- ----------
P0   P1    P11            6
P0   P1    P12            6
P0   P1                  12
P0   P2    P21            6
P0   P2    P22            6
P0   P2                  12
P0                       24
 

Indlægget ville se sådan ud:

INSERT INTO data (element, value) (SELECT coalesce(lvl2, lvl1, lvl0), sum_value FROM <query> d_out WHERE NOT EXISTS (SELECT NULL FROM data d_in WHERE d_in.element = coalesce(lvl2, lvl1, lvl0)));

Hvis højden af ​​bladknuderne er ukendt/ubegrænset, bliver dette mere behåret. Ovenstående tilgang ville ikke fungere, da ROLLUP skal vide præcis, hvor mange kolonner der skal tages i betragtning.

I så fald kan du bruge træstrukturen i en selv-join :

SQL> WITH HIERARCHY AS (
  2     SELECT t.element, path, VALUE
  3       FROM (SELECT sys_connect_by_path(t.element, '/') path,
  4                    connect_by_isleaf is_leaf, ELEMENT
  5                FROM tree t
  6               START WITH t.PARENT IS NULL
  7              CONNECT BY t.PARENT = PRIOR t.element) t
  8       LEFT JOIN DATA d ON d.element = t.element
  9                       AND t.is_leaf = 1
 10  )
 11  SELECT h.element, SUM(elements.value)
 12    FROM HIERARCHY h
 13    JOIN HIERARCHY elements ON elements.path LIKE h.path||'/%'
 14   WHERE h.VALUE IS NULL
 15   GROUP BY h.element
 16   ORDER BY 1;

ELEMENT SUM(ELEMENTS.VALUE)
------- -------------------
P0                       24
P1                       12
P11                       6
P12                       6
P2                       12
P21                       6
P22                       6
 


  1. Ugyldigt XML-format - Sådan undgår du dette

  2. Undtagelse:Der er allerede en åben DataReader tilknyttet denne forbindelse, som skal lukkes først

  3. En oversigt over PostgreSQL &MySQL krydsreplikering

  4. Kolonneantal for mysql.user er forkert. Forventet 42, fundet 44. Tabellen er sandsynligvis beskadiget