2016-12-05 4 views
3

У меня возникли проблемы с суммированием некоторого столбца в моем запросе с агрегацией. Немного сложно описать, что происходит, но я постараюсь изо всех сил:
У меня есть 3 стола - подробности, дополнительные детали и места. Места - это таблица, в которой есть места в мире. Подробности содержат сведения о произошедших событиях, а дополнительные сведения предоставляют дополнительные данные о событиях.
Каждое место имеет ID и ParentID (Как Нью-Йорк имеет ID и является его родителем ID является US. Что-то в этом роде). ID события (подробности) появляется несколько раз в виде столбца в таблице дополнительных данных. В таблице дополнительных данных также содержится ID того места, где произошло это событие.
ОК после всего того, чего я пытаюсь достичь, для каждого места сумма событий, которые там были. Я знаю, это звучит очень специфично, но это то, что клиент спросил.
Во всяком случае, пример того, к чему я пытаюсь добраться: NewYork 60, Chicago 20, Houston 10 Тогда у США будет 90. И он имеет несколько уровней.
Так что это то, что я пытаюсь сделать:
Сумма агрегирования в SQL (присоединяется)

With C(ID, NAME, COUNTT, ROOT_ID) as 
    (
     SELECT d.ID, d.NAME, 
      (SELECT COUNT(LX.ID) as COUNTT 
      FROM EXTRA LX 
      RIGHT JOIN d ON LX.PLACE_ID = d.ID -- **** 
      GROUP BY d.ID, d.NAME), 
      d.ID as ROOT_ID 
     FROM PLACES d 
     UNION ALL 
     SELECT d.ID, d.NAME, 
      (SELECT COUNT(LX.ID) as COUNTT 
      FROM EXTRA LX 
      RIGHT JOIN d ON LX.PLACE_ID = d.ID 
     GROUP BY d.ID, d.NAME), 
     C.ROOT_ID 
     FROM PLACES dx 
      INNER JOIN C ON dx.PARENT_ID = C.ID 
    ) 
    SELECT p.ID, p.NAME, S.SumIncludingChildren 
    FROM places p 
     INNER JOIN (
     SELECT ROOT_ID, SUM(COUNTT) as SumIncludingChildren 
     FROM C 
     GROUP BY ROOT_ID 
     ) S 
     ON p.ID = S.ROOT_ID 
    ORDER BY p.ID; 


деталей таблицы только для показа своих данных. Я добавлю это позже. Это только сравнение соответствующих столбцов. Чтобы это работало, мне это не нужно. Только для данных сайта.
Это не работает, потому что он не распознает «d», где находится «****». Если я положу «новый экземпляр» этой таблицы, это тоже не сработает. Поэтому я попытался реплицировать то, что нужно сделать, сделав 'NOT EXISTS IN' по запросу, который получает все места вместо правильного соединения ... on. Та же проблема.
Может быть, я чего-то не понимаю. Но я действительно ищу решение и какое-то объяснение. Я знаю, что мой код не идеален. Спасибо заранее.

EDIT: Я использую OracleSQL на Жаба 10.6

+0

Может быть, вы могли бы добавить DESC ваших таблиц? – sers

ответ

1
create table p(id number, up number, name varchar2(100)); 
create table e(id number, pid number, dsc varchar2(100)); 

insert into p values (1, null, 'country'); 
insert into p values (2, 1, 'center'); 
insert into p values (3, 1, 'province'); 
insert into p values (4, 2, 'capital'); 
insert into p values (5, 2, 'suburb'); 
insert into p values (6, 3, 'forest'); 
insert into p values (7, 3, 'village'); 
insert into p values (8, 7, 'shed'); 
insert into p values (9, 2, 'gov'); 

insert into e values (1, 8, 'moo'); 
insert into e values (2, 8, 'clank'); 
insert into e values (3, 7, 'sowing'); 
insert into e values (4, 6, 'shot'); 
insert into e values (5, 6, 'felling'); 
insert into e values (6, 5, 'train'); 
insert into e values (7, 5, 'cottage'); 
insert into e values (8, 5, 'rest'); 
insert into e values (9, 4, 'president'); 
insert into e values (10,1, 'GNP'); 
commit; 

with 
    places as 
    (select id, 
      up, 
      connect_by_root id as root, 
      level lvl 
     from p 
    connect by prior id = up), 
    ev_stats as 
    (select root as place, max(lvl) as max_lvl, count(e.id) as ev_count 
     from places left outer join e 
     on places.id = e.pid 
    group by root) 
select max_lvl, p.name, ev_count 
    from ev_stats inner join p on p.id = ev_stats.place 
order by max_lvl desc; 
+0

Эй, похоже, сработает. Может быть, мне нужно немного подружиться. Но можете ли вы немного объяснить, что вы здесь сделали? Мне трудно понять. –

+0

@AmitToren 'places' подзапросы построят множество деревьев (целые корни-> ветвь-> листы будут более конкретными (попробуйте' sys_connect_by_path (id, '->') путь' для визуализации)). Каждое место производит свое дерево (цепь). Дедушка, папа, сын и дочь произведут набор: (дед-> отец-> сын, дедушка-> отец-> дочь, дед-> папа, дедушка, папа-> сын, папа-> дочь, папа, сын, дочь). Подзапрос 'ev_stats' объединяет множество деревьев с событиями, имевшими место в листовом узле, и группирует события с помощью root. Итак, дедушка собирает свои собственные события, собственные события отца и детские события и т. Д. Заключительный запрос объединяет статистику с именами. –

+0

Удивительно. Большое спасибо. –