如何使用联接和分组依据执行多个 table 计算
How to perform multiple table calculation with joins and group by
我有两个 tables 客户端和分组。它们看起来像这样:
客户端
- C_id
- C_grouping_id
- 月份
- 利润
分组
- Grouping_id
- 月份
- 利润
客户 table 包含每个客户的每月利润,每个客户都属于 C_grouping_id 指定的特定分组方案。
分组 table 包含所有组及其每月利润。
我正在努力处理一个基本上计算每个订阅者每月剩余的查询:
残差=(订阅者月利润-分组月利润)*(订阅者所有月份的平均月利润/分组订阅者所属所有月份的平均利润)
到目前为止,我提出了以下查询,但结果似乎不正确:
SELECT client.C_id, client.C_grouping_Id, client.Month,
((client.Profit - grouping.profit) * (avg(client.Profit)/avg(grouping.profit))) as "residual"
FROM client
INNER JOIN grouping
ON "C_grouping_id"="Grouping_id"
group by client.C_id, client.C_grouping_Id,client.Month, grouping.profit
如果有人能阐明我做错了什么以及如何纠正它,我将不胜感激。
编辑:添加示例数据和所需结果
客户
C_id C_grouping_id Month Profit
001 aaa jul 10$
001 aaa aug 12$
001 aaa sep 8$
016 abc jan 25$
016 abc feb 21$
分组
Grouping_id Month Profit
aaa Jul 30$
aaa aug 50$
aaa Sep 15$
abc Jan 21$
abc Feb 27$
查询结果:
C_ID C_grouping_id Month Residual
001 aaa Jul (10-30)*(10/31.3)=-6.38
...每个客户每个月以此类推。
这可以通过非常直接的方式完成。
主要困难显然是您尝试同时处理不同级别的聚合(组和客户端的平均值以及当前记录)。
这更像是 difficult/clumsy 和简单的 SELECT FROM GROUP BY-SQL。
但是使用分析函数 Window functions 这很容易。
开始组合 table 并计算基数:
select c.c_id as client_id,
c.c_grouping_id as grouping_id,
c.month,
c.profit as client_profit,
g.profit as group_profit,
avg (c.profit) over (partition by c.c_id) as avg_client_profit,
avg (g.profit) over (partition by g.grouping_id) as avg_group_profit
from client c inner join grouping g
on c."C_GROUPING_ID"=g."GROUPING_ID"
and c. "MONTH" = g. "MONTH";
有了这个,您已经获得了客户和 grouping_id 的平均利润。
请注意,我将货币列的数据类型更改为 DECIMAL (10,3),因为带有 $ 符号的 VARCHAR 很难转换。
我还修复了 MONTHS 的数据,因为测试数据包含不同的 upper/lower 大小写拼写,这会阻止连接工作。
最后我把所有的列名都变成了大写的to,为了打字更方便。
总之,运行 这为您提供了以下结果集:
CLIENT_ID GROUPING_ID MONTH CLIENT_PROFIT GROUP_PROFIT AVG_CLIENT_PROFIT AVG_GROUP_PROFIT
16 abc JAN 25 21 23 24
16 abc FEB 21 27 23 24
1 aaa JUL 10 30 10 31.666
1 aaa AUG 12 50 10 31.666
1 aaa SEP 8 15 10 31.666
从这里到残差计算只差一步了。
您可以将此当前 SQL 放入视图中以使其可重复用于其他查询,或者将其用作内联视图。
我选择将它用作常见的 table 表达式 (CTE),又名 WITH 子句,因为它很好看且易于阅读:
with p as
(select c.c_id as client_id,
c.c_grouping_id as grouping_id,
c.month,
c.profit as client_profit,
g.profit as group_profit,
avg (c.profit) over (partition by c.c_id) as avg_client_profit,
avg (g.profit) over (partition by g.grouping_id) as avg_group_profit
from client c inner join grouping g
on c."C_GROUPING_ID"=g."GROUPING_ID"
and c. "MONTH" = g. "MONTH")
select client_id, grouping_id, month,
client_profit, group_profit,
avg_client_profit, avg_group_profit,
round( (client_profit - group_profit)
* (avg_client_profit/avg_group_profit), 2) as residual
from p
order by grouping_id, month, client_id;
注意整个语句是多么容易阅读,残差计算是多么直接。
结果是这样的:
CLIENT_ID GROUPING_ID MONTH CLIENT_PROFIT GROUP_PROFIT AVG_CLIENT_PROFIT AVG_GROUP_PROFIT RESIDUAL
1 aaa AUG 12 50 10 31.666 -12
1 aaa JUL 10 30 10 31.666 -6.32
1 aaa SEP 8 15 10 31.666 -2.21
16 abc FEB 21 27 23 24 -5.75
16 abc JAN 25 21 23 24 3.83
干杯,
拉斯
我有两个 tables 客户端和分组。它们看起来像这样:
客户端
- C_id
- C_grouping_id
- 月份
- 利润
分组
- Grouping_id
- 月份
- 利润
客户 table 包含每个客户的每月利润,每个客户都属于 C_grouping_id 指定的特定分组方案。
分组 table 包含所有组及其每月利润。
我正在努力处理一个基本上计算每个订阅者每月剩余的查询:
残差=(订阅者月利润-分组月利润)*(订阅者所有月份的平均月利润/分组订阅者所属所有月份的平均利润)
到目前为止,我提出了以下查询,但结果似乎不正确:
SELECT client.C_id, client.C_grouping_Id, client.Month,
((client.Profit - grouping.profit) * (avg(client.Profit)/avg(grouping.profit))) as "residual"
FROM client
INNER JOIN grouping
ON "C_grouping_id"="Grouping_id"
group by client.C_id, client.C_grouping_Id,client.Month, grouping.profit
如果有人能阐明我做错了什么以及如何纠正它,我将不胜感激。
编辑:添加示例数据和所需结果
客户
C_id C_grouping_id Month Profit
001 aaa jul 10$
001 aaa aug 12$
001 aaa sep 8$
016 abc jan 25$
016 abc feb 21$
分组
Grouping_id Month Profit
aaa Jul 30$
aaa aug 50$
aaa Sep 15$
abc Jan 21$
abc Feb 27$
查询结果:
C_ID C_grouping_id Month Residual
001 aaa Jul (10-30)*(10/31.3)=-6.38
...每个客户每个月以此类推。
这可以通过非常直接的方式完成。 主要困难显然是您尝试同时处理不同级别的聚合(组和客户端的平均值以及当前记录)。
这更像是 difficult/clumsy 和简单的 SELECT FROM GROUP BY-SQL。 但是使用分析函数 Window functions 这很容易。
开始组合 table 并计算基数:
select c.c_id as client_id,
c.c_grouping_id as grouping_id,
c.month,
c.profit as client_profit,
g.profit as group_profit,
avg (c.profit) over (partition by c.c_id) as avg_client_profit,
avg (g.profit) over (partition by g.grouping_id) as avg_group_profit
from client c inner join grouping g
on c."C_GROUPING_ID"=g."GROUPING_ID"
and c. "MONTH" = g. "MONTH";
有了这个,您已经获得了客户和 grouping_id 的平均利润。 请注意,我将货币列的数据类型更改为 DECIMAL (10,3),因为带有 $ 符号的 VARCHAR 很难转换。 我还修复了 MONTHS 的数据,因为测试数据包含不同的 upper/lower 大小写拼写,这会阻止连接工作。 最后我把所有的列名都变成了大写的to,为了打字更方便。
总之,运行 这为您提供了以下结果集:
CLIENT_ID GROUPING_ID MONTH CLIENT_PROFIT GROUP_PROFIT AVG_CLIENT_PROFIT AVG_GROUP_PROFIT
16 abc JAN 25 21 23 24
16 abc FEB 21 27 23 24
1 aaa JUL 10 30 10 31.666
1 aaa AUG 12 50 10 31.666
1 aaa SEP 8 15 10 31.666
从这里到残差计算只差一步了。 您可以将此当前 SQL 放入视图中以使其可重复用于其他查询,或者将其用作内联视图。
我选择将它用作常见的 table 表达式 (CTE),又名 WITH 子句,因为它很好看且易于阅读:
with p as
(select c.c_id as client_id,
c.c_grouping_id as grouping_id,
c.month,
c.profit as client_profit,
g.profit as group_profit,
avg (c.profit) over (partition by c.c_id) as avg_client_profit,
avg (g.profit) over (partition by g.grouping_id) as avg_group_profit
from client c inner join grouping g
on c."C_GROUPING_ID"=g."GROUPING_ID"
and c. "MONTH" = g. "MONTH")
select client_id, grouping_id, month,
client_profit, group_profit,
avg_client_profit, avg_group_profit,
round( (client_profit - group_profit)
* (avg_client_profit/avg_group_profit), 2) as residual
from p
order by grouping_id, month, client_id;
注意整个语句是多么容易阅读,残差计算是多么直接。 结果是这样的:
CLIENT_ID GROUPING_ID MONTH CLIENT_PROFIT GROUP_PROFIT AVG_CLIENT_PROFIT AVG_GROUP_PROFIT RESIDUAL
1 aaa AUG 12 50 10 31.666 -12
1 aaa JUL 10 30 10 31.666 -6.32
1 aaa SEP 8 15 10 31.666 -2.21
16 abc FEB 21 27 23 24 -5.75
16 abc JAN 25 21 23 24 3.83
干杯, 拉斯