CONNECT BY для двух таблиц с двумя соединениями - PullRequest
2 голосов
/ 10 сентября 2010

У меня есть 3 таблицы:

  • две с иерархическими структурами
    (как "измерения" рекурсивного типа иерархии);
  • один с суммированием данных (например, «факты» со столбцом X).

Они здесь:

  1. DIM1 (ID1, PARENT2, NAME1)
  2. DIM2 (ID2, PARENT2, NAME2)
  3. FACTS (ID1, ID2, X)

Пример таблицы DIM1:

--        1   0  DIM1  
----      2   1  DIM1-A  
------    3   2  DIM1-A-A  
--------  4   3  DIM1-A-A-A  
--------  5   3  DIM1-A-A-B  
------    6   2  DIM1-A-B  
--------  7   6  DIM1-A-B-A  
--------  8   6  DIM1-A-B-B  
------    9   2  DIM1-A-C  
----     10   1  DIM1-B  
------   11  10  DIM1-B-C  
------   12  10  DIM1-B-D  
----     13   1  DIM1-C  

Пример таблицы DIM2:

--        1   0  DIM2  
----      2   1  DIM2-A  
------    3   2  DIM2-A-A  
--------  4   3  DIM2-A-A-A  
--------  5   3  DIM2-A-A-B  
--------  6   3  DIM2-A-B-C  
------    7   2  DIM2-A-B  
----      8   1  DIM2-B  
----      9   1  DIM2-C  

Пример таблицы FACTS:

 1   1  100  
 1   2   30  
 1   3  500  
 --    ................  
 13  9  200  

И я хотел бы создать единственное SELECT, где я буду указывать родителя для DIM1 (например, ID1=2 для DIM1-A) и родителя для DIM2 (например, ID2=2 для DIM2-A) и SELECT сгенерирует отчет, подобный этому:

Name_of_1 Name_of_2 Sum_of_X  
--------- --------- ----------  
DIM1-A-A  DIM2-A-A  (some sum)  
DIM1-A-A  DIM2-A-B  (some sum)  
DIM1-A-B  DIM2-A-A  (some sum)  
DIM1-A-B  DIM2-A-B  (some sum)  
DIM1-A-C  DIM2-A-A  (some sum)  
DIM1-A-C  DIM2-A-B  (some sum)  

Я хотел бы использовать фразу CONNECT BY, фразу START WITH, фразу SUM,GROUP BY фраза и OUTER или INNER (?) JOIN.Мне не нужны другие расширения Oracle 10.2.

Другими словами: только с «классическим» SQL и
только расширения Oracle для запросов иерархии.

Возможно ли это?

Я попытался провести несколько экспериментов с вопросом в
Смешивание. Соединение, внутреннее объединение и суммирование с Oracle

(где очень хорошее решение но только для одна
таблица измерений ("Задачи"), но мне нужно JOIN две таблицы измерений для одной таблицы фактов), но я не был успешным.

Ответы [ 2 ]

2 голосов
/ 10 сентября 2010

«Некоторая сумма» не очень описательна, поэтому я не понимаю, зачем вам вообще нужно CONNECT BY.

SELECT  dim1.name, dim2.name, x
FROM    (
        SELECT  id1, id2, SUM(x) AS x
        FROM    facts
        GROUP BY
                id1, id2
        ) f
JOIN    dim1
ON      dim1.id = f.id1
JOIN    dim2
ON      dim2.id = f.id2
0 голосов
/ 11 сентября 2010

Я думаю, что вы пытаетесь получить сумму значений в таблице фактов для всех дочерних элементов указанных строк, сгруппированных по верхним дочерним элементам. Это означает, что в приведенном выше примере результаты для первой строки будут суммой любых пересечений (DIM1-AA, DIM1-AAA, DIM1-AAB) и (DIM2-AA, DIM2-AAA, DIM2-AAB, DIM3 -AAC) найдено в таблице ФАКТОВ. Исходя из этого предположения, я пришел к следующему решению:

SELECT root_name1, root_name2, SUM(X)
FROM ( SELECT CONNECT_BY_ROOT(name1) AS root_name,
             id1
         FROM dim1
      CONNECT BY parent1 = PRIOR id1
      START WITH parent1 = 2) d1
     CROSS JOIN
     ( SELECT CONNECT_BY_ROOT(name2) AS root_name,
              id2
         FROM dim2
      CONNECT BY parent2 = PRIOR id2
      START WITH parent2 = 2) d2
     LEFT OUTER JOIN
     facts
     ON     d1.id1 = facts.id1
        AND d2.id2 = facts.id2
GROUP BY root_name1, root_name2

(Это также предполагает, что столбцы FACTS имеют имена ID1, ID2 и X).

...