【问题标题】:SQL Complex Conditional AggregationSQL 复杂条件聚合
【发布时间】:2020-05-08 20:49:10
【问题描述】:

我想计算PL中每支球队的积分

我有两张桌子

T1

---------------------
TEAM ID || TEAM NAME
---------------------
01      || Liverpool
02      || Man City
---------------------

以 t2 为例

----------------------------------------------------------------
MATCH ID || HOME TEAM || AWAY TEAM || HOME GOALS || AWAY GOALS|
-----------------------------------------------------------------
30       || Liverpool || Man City  || 1          || 0 
-----------------------------------------------------------------

计算积分 现在对于每场比赛,如果一支球队的进球数大于另一支球队,他赢了,他得 3 分,输家得 0 分 但是,如果他们每个人的进球数相同,那么他们每个人都只得 1 分。

新表应该是这样的

-----------------------------------
Team ID || Team Name || Team Points
------------------------------------
01      || Liverpool || 28
02      || Man City  || 22
------------------------------------

【问题讨论】:

  • 您的第二个表应该存储 TEAM ID 用于 AWAY TEAMHOME TEAM 而不是团队名称,以便可以轻松地加入表 1。
  • 是的,但事实并非如此。看,我试图在内部连接中将 t2 分解为两个单独的表(t2 H 代表主机,t2 G 代表客人),重点是 :: 是否可以求和(H.HomeGoals> G.GuestGoals 然后为 3 时的情况否则 0) 等等 ..??恐怕不对

标签: sql postgresql


【解决方案1】:

加入表格并使用条件聚合:

select t1.teamid, t1.teamname,
  sum(
    case sign((homegoals - awaygoals) * case when t1.teamname = t2.hometeam then 1 else -1 end)
      when 1 then 3
      when 0 then 1
      when -1 then 0
    end
  ) teampoints
from t1 inner join t2
on t1.teamname in (t2.hometeam, t2.awayteam)
group by t1.teamid, t1.teamname

请参阅demo

【讨论】:

  • 非常感谢您的帮助和您的时间。多么干净。这么好的思维方式
  • 很高兴它有帮助。
  • ON 子句中的条件是:on t1.teamname in (t2.hometeam, t2.awayteam),所以只有两种情况:t1.teamname = t2.hometeamt1.teamname = t2.awayteam。这就是为什么case when t1.teamname = t2.hometeam then 1 else -1 end 只检查 2 个案例。这个 1 或 -1 是乘以目标差异的一个因素。
  • 是的。谢谢你的解释,forbas。
【解决方案2】:

我建议横向连接:

select t1.team_id, t1.team_name, sum(v.goals),
       sum(case when goals > other_goals then 3 
                when goals = other_goals then 1
                else 0
           end) as points
from t2 cross join lateral
     (values (t2.home_team, t2.home_goals,  t2.away_goals),
             (t2.away_team, t2.away_goals, t2.home_goals)
     ) v(team, goals, other_goals) join
     t1
     on v.team = t1.team_id
group by t1.team_id, t1.team_name;

【讨论】:

  • 这样一个绝妙的解决方案 Gordon,但是您将如何计算分数?
  • @Nash 。 . .一样的方法。当我第一次阅读“分数”与“分数”不同的问题时,我并不清楚。
  • 如此迷人的一段代码。但根据新表应该是什么,我们不需要Sum (V. Goals)。然而,这是伟大的工作。感谢您的帮助。
【解决方案3】:

您可以加入表格并进行条件求和:

select
    t1.team_id,
    t1.team_name,
    sum(
        case 
            when t2.home_goals = t2.away_goals then 1
            when 
                ( t1.team_name = t2.home_team and t2.home_goals > t2.away_team)
                or (t1.team_name = t2.away_team and t2.away_goals > t2.home_team)
                then 3
            else 0 
        end
    ) team_points
from t1
inner join t2 on t1.team_name in (t2.home_team, t2.away_team)
group by t1.team_id, t1.team_name

sum() 中,case 表达式检查游戏的结果并根据需要分配分数(获胜的游戏为 3 分,平局为 1 分,失败为 0 分)。

注意:正如 cmets 中所说,您应该修改架构以将团队的 ids 存储在分数表中,而不是他们的名称。

【讨论】:

  • 非常感谢 GMB 的帮助和您的时间。
  • 但是 t1 中没有目标!,我想你想说``当 t2.home_goals = t2.guest_goals 然后 1`` 对吗?
  • @Nash:你是对的。我刚刚修改了答案中的查询。
  • 我想,你也想说:``When(t1.team_name = t2.home_team and t2.home_goals > t2.away_goals),我的意思是最后一列是目标而不是名称,对吗?
【解决方案4】:

现在,这个呢

SELECT t1.teamid,
        t1.teamname,
        SUM (CASE   WHEN    t1.teamname = t2.hometeam
                            AND     t2.homegoals > t2.awaygoals THEN    3
                    WHEN    t1.teamname =   t2.awayteam
                            AND     t2.homegoals < t2.awaygoals THEN    3
                    WHEN    t1.teamname IN (t2.hometeam, t2.awayteam)
                            AND     t2.homegoals = t2.awaygoals THEN    1
                    ELSE    0
                    END
             )AS    "Team Points"

FROM    t1
        INNER JOIN
        t2
        ON
        t1.teamname IN (t2.hometeam, t2.awayteam)

GROUP BY t1.teamid,
        t1.teamname

这是Demo

【讨论】:

    猜你喜欢
    • 2012-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-04
    • 1970-01-01
    • 2019-03-14
    相关资源
    最近更新 更多