2016-12-05 2 views
3

집계를 사용하여 쿼리에서 일부 열을 합산하는 데 문제가 있습니다. 무슨 일이 일어 났는지 설명하는 것은 약간 어렵지만 최선을 다할 것입니다.
세부 정보, 세부 정보 및 장소가 3 개인 테이블이 있습니다. 장소는 세계의 장소가 포함 된 표입니다. 세부 정보에는 발생한 이벤트에 대한 세부 정보가 포함되어 있으며 추가 세부 정보는 이벤트에 대한 더 많은 데이터를 제공합니다.
각 위치는 IDParentID입니다 (뉴욕처럼 ID이 있고 IDUS입니다.). 이벤트 (세부 사항)의 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'을 수행하여 올바른 조인을 복제하려고했습니다 .... 같은 문제.
아마도 내가 뭔가를 얻지 못합니다. 그러나 나는 정말로 해결책과 약간의 설명을 찾고있다. 내 코드가 완벽하지 않다는 것을 안다. 미리 감사드립니다.

편집 : 나는 어쩌면 당신은 당신의 테이블의 DESC를 추가 할 수

+0

두꺼비 10.6 OracleSQL을 사용하고 있습니다? – 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

이봐, 작동하는 것 같다. 어쩌면 나는 그것을 약간 tweek해야합니다. 하지만 여기서 한 짓을 조금 설명 할 수 있니? 나는 이해하는 데 어려움을 겪고있다. –

+0

@AmitToren'places' 하위 쿼리는 트리 집합을 구성합니다 (루트 -> 분기 -> 리프를 더 구체적으로 나타냅니다 (시각화 할'sys_connect_by_path (id, '->'path '))). 각 장소는 자신의 나무 (체인)를 생산합니다. 할아버지, 아빠, 아들, 딸은 할아버지 -> 아빠 -> 아들, 할아버지 -> 아빠 -> 딸, 할아버지 -> 할아버지, 아빠 -> 아들, 아빠 -> 딸, 아빠, 아들, 딸). 'ev_stats' 서브 쿼리는 리프 노드에서 일어난 이벤트로 트리 세트를 조인하고 루트별로 이벤트를 그룹화합니다. 그래서 할아버지는 자신의 사건, 아빠 자신의 사건과 어린이 사건 등을 수집합니다. 최종 질의는 통계와 이름을 결합합니다. –

+0

놀라운. 고마워. –