【问题标题】:Whats wrong with my query with CASE statement我的 CASE 语句查询有什么问题
【发布时间】:2014-05-29 16:51:32
【问题描述】:

我正在尝试解决http://www.sqlzoo.net/wiki/The_JOIN_operation上的#13

“如图所示列出每场比赛以及每支球队的进球数。这将使用“CASE WHEN”,这在之前的任何练习中都没有解释过。”

这是我的查询:

SELECT game.mdate, game.team1, 
SUM(CASE WHEN goal.teamid = game.team1 THEN 1 ELSE 0 END) AS score1,
game.team2,
SUM(CASE WHEN goal.teamid = game.team2 THEN 1 ELSE 0 END) AS score2

FROM game INNER JOIN goal ON matchid = id
GROUP BY game.id
ORDER BY mdate,matchid,team1,team2

我得到“行太少”的结果。我不明白我错了哪一部分。

【问题讨论】:

  • 在单独的列上,您必须具有聚合函数或将它们添加到 GROUP BY。我认为该消息是 sqlzoo 的自定义消息。
  • 您错过了 0-0 的比分,因此您需要扩大连接范围以包含所有 game 行,包括 goal 表中未列出的行。
  • 你需要使用join分别获取每个团队的分数

标签: mysql sql select group-by case


【解决方案1】:

INNER JOIN 只返回有进球的比赛,即goalgame 表之间的比赛。

您需要的是LEFT JOIN。您需要第一个表 game 中的所有行,但它们不需要匹配 goal 中的所有行,根据我对您的问题的 0-0 评论:

SELECT game.mdate, game.team1, 
SUM(CASE WHEN goal.teamid = game.team1 THEN 1 ELSE 0 END) AS score1,
game.team2,
SUM(CASE WHEN goal.teamid = game.team2 THEN 1 ELSE 0 END) AS score2

FROM game LEFT JOIN goal ON matchid = id
GROUP BY game.id,game.mdate, game.team1, game.team2 
ORDER BY mdate,matchid,team1,team2

这将返回 6 月 27 日葡萄牙和西班牙之间的 0-0 结果,您最初的答案错过了。

【讨论】:

    【解决方案2】:

    由于现在两个表中都有同名的列,因此无需指定当前列的来源。

    SELECT mdate, team1, 
    
    SUM(CASE WHEN teamid = team1 THEN 1 ELSE 0 END) AS score1,
    

    团队2,

    SUM(CASE WHEN teamid = team2 THEN 1 ELSE 0 END) AS score2
    
    FROM game LEFT JOIN goal ON matchid = id
    
    GROUP BY mdate, team1, team2
    
    ORDER BY mdate,matchid,team1,team2
    

    【讨论】:

      【解决方案3】:
      SELECT game.mdate, game.team1, 
      SUM(CASE WHEN goal.teamid = game.team1 THEN 1 ELSE 0 END) score1,
      game.team2,
      SUM(CASE WHEN goal.teamid = game.team2 THEN 1 ELSE 0 END) score2
      FROM game LEFT JOIN goal ON matchid = id
      GROUP BY mdate, team1, team2
      

      【讨论】:

        【解决方案4】:

        我是使用子查询完成的。

        这里唯一的技巧是要了解我们需要使用左连接而不是内连接,因为如果我们使用内连接(0-0 情况),有些游戏的得分为 0,在我们的查询中不会捕获这些目标

        希望下面的查询有所帮助!

        select t1.mdate,t1.team1,sum(t1.score1),t1.team2,sum(t1.score2) from(
        SELECT mdate,
          team1,
          CASE WHEN teamid=team1 THEN 1 ELSE 0 END score1,
          team2,
          CASE WHEN teamid=team2 THEN 1 ELSE 0 END score2
          FROM game JOIN goal ON matchid = id)t1
        group by t1.mdate,t1.team1,t1.team2
        order by mdate,team1,team2
        

        【讨论】:

          【解决方案5】:

          对于 MySQL,@mjsqu 的答案有效,但 for SQL Server 和其他一些方言您需要在 GROUP BY 中使用 specify all the columns。因此,如果您熟悉 MySQL,请记住,在某些方言中,您必须更具体地使用 GROUP BY(不幸的是......)。在适用于 SQL Server 的脚本下:

          SELECT    game.mdate 
          ,         game.team1
          ,         SUM(CASE WHEN goal.teamid=game.team1 THEN 1 ELSE 0 END) score1 
          ,         game.team2
          ,         SUM(CASE WHEN goal.teamid=game.team2 THEN 1 ELSE 0 END) score2
          FROM game LEFT JOIN goal 
            ON game.id=goal.matchid
          GROUP BY  game.mdate, goal.matchid, game.team1, game.team2
          

          【讨论】:

            【解决方案6】:

            `

            SELECT ga.mdate, ga.team1,
            SUM(CASE WHEN go.teamid=ga.team1 THEN 1 ELSE 0 END) score1,
            ga.team2,
            SUM(CASE WHEN go.teamid=ga.team2 THEN 1 ELSE 0 END) score2
            FROM game ga LEFT JOIN goal go ON go.matchid = ga.id
            GROUP BY ga.mdate, go.matchid, ga.team1, ga.team2
            

            `

            【讨论】:

            • 请为您的答案添加解释,因为这不会帮助某人解决或理解问题。
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2021-08-09
            • 2014-02-11
            • 2012-08-21
            • 1970-01-01
            • 1970-01-01
            • 2013-10-29
            相关资源
            最近更新 更多