想要从 ORACLE SQL 中的 2 个单独的列中为一个团队提供平均点
Posted
技术标签:
【中文标题】想要从 ORACLE SQL 中的 2 个单独的列中为一个团队提供平均点【英文标题】:want avg point for one team from 2 separate columns in ORACLE SQL 【发布时间】:2020-05-10 12:43:33 【问题描述】:游戏桌:
GAME_ID - NUMBER
GAME_DATE - DATE
ARENA - VARCHAR2(20)
HOME - VARCHAR2(30)
AWAY - VARCHAR2(30)
"HOME POINT" - NUMBER
"AWAY POINT" - NUMBER
HOME 和 AWAY 标识球队名称。 “HOME POINT”和“AWAY POINT”对应于这些列。例如(仅表示为 4 列),我想获得一支球队的平均分。考虑下面的示例,我想获得 AAA、BBB、CCC 和 DDD 团队的 AVG 积分。
AAA
BBB
90 <- got by AAA
100 <- got by BBB
------------------------
AAA
CCC
99 <- got by AAA
82 <- got by CCC
------------------------
AAA
DDD
100 <- got by AAA
78 <- got by CCC
我尝试了下面的代码,但结果并不理想:
SELECT HOME, SUM("HOME POINT") + SUM("AWAY POINT") / COUNT(*)
FROM GAME
GROUP BY HOME
【问题讨论】:
【参考方案1】:取消透视数据并聚合一种方法使用union all
:
select team, avg(points)
from ((select home as team, home_points as points from games) union all
(select away as team, away_points as points from games)
) t
group by team;
在 Oracle 12C+ 中,我建议使用横向连接而不是 union all
。
【讨论】:
【参考方案2】:下面是横向连接的方法;从版本 12c 开始,此语法在 Oracle 中可用,在这种情况下,它比 union all
更有效,因为它不需要扫描表两次:
select t.team, avg(t.points) avg_points
from games g
cross apply (
select home team, home_points points from dual
union all select away, away_points points from dual
) t
group by t.team
旁注:
我建议将点存储为int
而不是数字(大概,点没有小数部分)
使用不需要引用的列名(home_points
优于 "home point"
)
这个 demo on DB Fiddle 与您的示例数据产生:
团队 | AVG_POINTS :--- | ---------: AAA | 96.33 血脑屏障 | 100 CCC | 82 DDD | 78【讨论】:
【参考方案3】:with points as (
select home as team, sum("HOME POINT") as point_sum,
count("HOME POINT") as point_qty
from game
group by home
having count("HOME POINT")!=0
union all
select away as team, sum("AWAY POINT") as point_sum,
count("AWAY POINT") as point_qty
from game
group by away
having count("AWAY POINT")!=0
)
select team, sum(point_sum)/sum(point_qty) as avg_point
from points
group by team;
【讨论】:
以上是关于想要从 ORACLE SQL 中的 2 个单独的列中为一个团队提供平均点的主要内容,如果未能解决你的问题,请参考以下文章
(Oracle) SQL 中的正则表达式将日期/时间拆分为单独的日期和时间列