带聚合的硬查询

时间:2014-10-01 18:57:57

标签: sql oracle average

我使用的是Oracle SQL,我需要有关硬查询的帮助。

我有两张桌子 (table_A):

GroupID (int)
ClientID (int)
Age (int)

table_B):

GroupID (int)
Budget (int)

我的查询应该针对每组客户端进行:

  • 计算小组的平均年龄
  • 计算平均预算 每个客户的年龄,如平均年龄(年龄可以更大或更小) 1)。例如:Average_Age - 1< Average_Age< Average_Age + 1。
  • Output value :(预算)/(平均预算)

例如: table_A

GroupID | ClientID  | Age
    A   |   11      | 26
    A   |   22      | 27
    A   |   33      | 21
    B   |   44      | 22
    B   |   55      | 29
    B   |   66      | 25
    C   |   77      | 23
    C   |   88      | 22
    C   |   99      | 20
    D   |   111     | 24
    D   |   222     | 26
    D   |   333     | 25

table_B

GroupID | Budget
   A    |  100
   B    |  200
   C    |  300
   D    |  400

表中没有任何值是固定的。 A组输出值的计算示例:

  • A组的平均年龄:(27 + 27 + 21)/ 3 = 24.6
  • 年龄为23-25岁的ClientID为:66,77,111,333。他们的平均预算为: (200 + 300 + 400 * 2)/ 4 = 325
  • 输出值应为:100/325 = 0.307

输出表应为

 GroupID    |  Output Value
    A       |     0.307
    B       |     ....
    C       |     ....
    D       |     ....

有任何建议如何做到这一点?我尝试了很多方法。我感到迷茫。

2 个答案:

答案 0 :(得分:1)

准备测试数据(名称和类型中的固定拼写错误):

drop table table_a;

create table table_a(
GroupID  varchar2(10),
ClientID int,
Age      int
);

drop table table_b;

create table table_b(
GroupID varchar2(10),
Budget  int
);


insert into table_a values('A',   11  , 26);
insert into table_a values('A',   22  , 27);
insert into table_a values('A',   33  , 21);
insert into table_a values('B',   44  , 22);
insert into table_a values('B',   55  , 29);
insert into table_a values('B',   66  , 25);
insert into table_a values('C',   77  , 23);
insert into table_a values('C',   88  , 22);
insert into table_a values('C',   99  , 20);
insert into table_a values('D',   111 , 24);
insert into table_a values('D',   222 , 26);
insert into table_a values('D',   333 , 25);

insert into table_b values('A',   100);
insert into table_b values('B',   200);
insert into table_b values('C',   300);
insert into table_b values('D',   400);

commit;

查询本身:

select a1.GroupId, a2.groupid, a2.clientid, b1.budget/avg(b2.budget) over(partition by a1.groupid) as avg_budget
 from (select GroupId, trunc(avg(age)) as avg_age
        from table_a
       group by GroupId
     ) a1
 inner join table_a a2
    on a2.age between a1.avg_age - 1 and a1.avg_age + 1
 inner join table_b b1
    on b1.groupid = a1.groupid    
 inner join table_b b2
    on b2.groupid = a2.groupid    
order by a1.GroupId, a2.clientid
;            

结果:

GROUPID GROUPID_1   CLIENTID    AVG_BUDGET
A   B   66  0.307692307692308
A   C   77  0.307692307692308
A   D   111 0.307692307692308
A   D   333 0.307692307692308
B   A   11  0.666666666666667
B   B   66  0.666666666666667
B   D   111 0.666666666666667
B   D   222 0.666666666666667
B   D   333 0.666666666666667
C   A   33  1.33333333333333
C   B   44  1.33333333333333
C   C   88  1.33333333333333
C   C   99  1.33333333333333
D   A   11  1.33333333333333
D   B   66  1.33333333333333
D   D   111 1.33333333333333
D   D   222 1.33333333333333
D   D   333 1.33333333333333

答案 1 :(得分:0)

select Q1.GroupID, Q2.Budget/Q1.Budget_avg as Output_value from
(
select GroupID,ClientID,avg(budget) as Budget_avg from table_A A,table_B B
where A.GroupID =B.GroupID
group by GroupID,ClientID
) Q1,(select GroupID,Budget from table_B) Q2
where Q1.GroupID = Q2.GroupID

你可以尝试一下,让我知道这是否适合你?