【问题标题】:Aggregation Sum in SQL (Joins)SQL 中的聚合总和(联接)
【发布时间】:2017-04-19 23:47:19
【问题描述】:

我在将查询中的某些列与聚合相加时遇到了一些问题。 描述正在发生的事情有点困难,但我会尽力而为:
我有 3 张桌子 - 细节、额外细节和地方。 Places 是一个包含世界各地地点的表。详细信息包含有关已发生事件的详细信息,额外的详细信息提供有关事件的更多数据。
每个地方都有一个ID 和一个ParentID(就像纽约有一个ID,它的父级IDUS。类似的东西)。事件(详细信息)的ID 在额外详细信息表中作为一列出现了多次。额外的详细信息表还包含该事件发生地点的ID
好吧,毕竟,我想要实现的是,对于每个地方,那里发生的事件的总和。我知道这听起来很具体,但这是客户要求的。
无论如何,我想要达到的示例: 纽约 60,芝加哥 20,休斯顿 10 然后美国将有 90。它有几个级别。
所以这就是我想要做的:

    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' 来复制正确连接...打开。同样的问题。
也许我什么都没有。但我真的在寻求解决方案和一些解释。我知道我的代码并不完美。 提前致谢。

编辑:我在 Toad 10.6 上使用 OracleSQL

【问题讨论】:

  • 也许您可以添加表格的描述?

标签: sql oracle join aggregation toad


【解决方案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;

【讨论】:

  • 嘿,它似乎工作。也许我需要稍微调整一下。但是你能解释一下你在这里做了什么吗?我很难理解。
  • @AmitToren places 子查询构造一组树(链根-> 分支-> 叶更具体(尝试sys_connect_by_path(id, '->') path 可视化))。每个地方都有自己的树(链)。爷爷,爸爸,儿子和女儿将产生集合:(爷爷->爸爸->儿子,爷爷->爸爸->女儿,爷爷->爸爸,爷爷,爸爸->儿子,爸爸->女儿,爸爸,儿子,女儿)。 ev_stats 子查询将一组树与发生在叶节点中的事件连接起来,并按根对事件进行分组。所以爷爷收集他自己的事件,爸爸自己的事件和孩子的事件等。最终查询将统计数据与名称连接起来。
  • 太棒了。非常感谢。
猜你喜欢
  • 1970-01-01
  • 2020-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多