如何为此逻辑编写SQL查询(has_many,belongs_to association)?

时间:2011-02-05 23:39:31

标签: sql mysql

此SQL查询的目标是返回具有最多战斗胜利和胜利计数的用户。

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

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

战斗有以下几个关注的栏目:

  • challenger_id(user_id fk)
  • challengee_id(user_id fk)
  • challenger_won(boolean)

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

  • 如果用户是挑战者并且challenger_won = true,那么它将被视为胜利。
  • 如果用户是挑战者且challenger_won = false,则认为是胜利。
  • 如果challenger_won = null,则忽略它。

我如何为此编写SQL?

1 个答案:

答案 0 :(得分:3)

这个怎么样?

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”为角色的行(对于“challengeR won”)以及战斗机ID和战斗胜利的计数。第二部分生成以'E'为角色的行(对于'challengeE won')和战斗机ID以及战斗胜利的计数。如果一些战斗机作为挑战者赢得3场战斗并且作为挑战者参加3场战斗,则该角色是必要的;没有角色,具有相同战斗机和计数的两个条目将折叠成一个。然后,您将为每个角色中的每个战斗机总结胜利。