2016-12-05 17 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、 ' - >')パス)))。それぞれの場所はそれ自身の木(鎖)を作り出します。おじいちゃん、お父さん、息子、娘、お父さん、お父さん、娘、おじいちゃん、祖父、おじいちゃん、お父さん、 )。 'ev_stats'サブクエリは、リーフノードで発生したイベントとツリーのセットを結合し、ルートによってイベントをグループ化します。だから、おじいちゃんは自分のイベント、お父さんのイベントや子供イベントなどを収集します。最終的なクエリは名前と統計情報を結合します。 –

+0

素晴らしい。どうもありがとう。 –