【问题标题】:How to write a SQL query for this logic (has_many, belongs_to association)?如何为此逻辑编写 SQL 查询(has_many、belongs_to 关联)?
【发布时间】:2011-02-06 23:44:49
【问题描述】:

此 SQL 查询的目标是返回战斗获胜次数最多的用户和获胜次数。

我有两个表:用户和战斗。

用户有很多战斗 战斗属于用户

Fight 关注以下几列:

  • challenge_id (user_id fk)
  • challenge_id (user_id fk)
  • challenge_won(布尔值)

如您所见,用户可以是挑战者或挑战者,但不能同时是两者。

  • 如果用户是挑战者并且challenger_won = true,则视为获胜。
  • 如果用户是挑战者并且challenge_won = false,则视为获胜。
  • 如果challenge_won = null,则忽略它。

我将如何为此编写 SQL?

【问题讨论】:

    标签: sql mysql


    【解决方案1】:

    这个怎么样?

    SELECT a.fighter, COUNT(*) AS wins
      FROM (SELECT challenger_id AS fighter
              FROM fights
             WHERE challenger_won = TRUE
            UNION ALL
            SELECT challengee_id AS fighter
              FROM fights
             WHERE challenger_won = FALSE
           ) AS a
     GROUP BY a.fighter;
    

    如果 challenger_won 为 NULL,则 UNION 中的两个查询都将根据需要忽略该行。

    如果你不喜欢 UNION ALL,你可以改用:

    SELECT a.fighter, SUM(a.wins) AS wins
      FROM (SELECT challenger_id AS fighter, 'R' AS role, COUNT(*) AS wins
              FROM fights
             WHERE challenger_won = TRUE
             GROUP BY fighter, role
            UNION
            SELECT challengee_id AS fighter, 'E' AS role, COUNT(*) AS wins
              FROM fights
             WHERE challenger_won = FALSE
             GROUP BY fighter, role
           ) AS a
     GROUP BY a.fighter;
    

    UNION 的第一部分生成以“R”作为角色(代表“挑战者获胜”)、战士 ID 和获胜次数的行。第二部分生成以“E”为角色的行(代表“challengeE won”)以及战斗机 ID 和赢得的战斗次数。该角色是必要的,以防某些战士以挑战者身份赢得 3 场战斗,以被挑战者身份赢得 3 场战斗;如果没有角色,具有相同战士和计数的两个条目将合并为一个。然后,您将每个角色中每个战士的胜利相加。

    【讨论】:

    • 当我运行第一个查询时,我收到一条错误消息,提示“每个派生表都必须有自己的别名”
    • @keruilin: 被指控有罪-我添加了缺少的“AS a”子句(因为如果您添加了“AS b”,那么您会收到未知表/别名“a”错误. 我还没有运行代码 - 正如你所知道的那样。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-02-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多