获取公会数量最多的游戏名称

Ila*_* WS 3 mysql

我有一个包含表的数据库:

我需要检索包含最多公会的游戏的名称。

公会由游戏分配。

我尝试的查询:

SELECT Name, Count(*) guildName
FROM Game game, Guild guild 
WHERE game.Name = Guild.gName
Run Code Online (Sandbox Code Playgroud)

并以某种方式使用 MAX 函数。

我有点困惑如何执行此操作,非常感谢任何帮助。

And*_*y M 5

一个明显的解决方案是获取所有计数,按降序对它们进行排序并仅检索最上面的行:

SELECT
  gName,
  COUNT(Name) AS GuildCount
FROM
  Guild
GROUP BY
  gName
ORDER BY
  GuildCount DESC
LIMIT
  0, 1
;
Run Code Online (Sandbox Code Playgroud)

这仅适用于只有一个游戏可以拥有最大数量的情况,但您可能无法保证这一点。所以上面的解决方案不是很好,因为如果两个或更多游戏具有相同的最高数字,你会说你想要获得所有这些名字。

所以,你可以试试这种方法:

SELECT
  gName,
  COUNT(Name) AS GuildCount
FROM
  Guild
GROUP BY
  gName
HAVING
  COUNT(Name) =
  (
    SELECT
      COUNT(Name)
    FROM
      Guild
    GROUP BY
      gName
    ORDER BY
      GuildCount DESC
    LIMIT
      0, 1
  )
;
Run Code Online (Sandbox Code Playgroud)

子查询将只获取公会数量和最高公会数量,而外部查询将获取那些具有匹配公会数量的游戏的名称。

上面的问题显然是你必须扫描表两次,每次执行相同的分组,而且分组本身也必须在代码中重复。问题是,如何避免这种情况?

现在,其他 SQL 平台提供强大的工具(如排名函数),而 MySQL 正试图通过允许您使用变量来实现更好的性能来弥补。在这种情况下,也可以使用变量一次性获得结果并避免逻辑重复。这是一种方法:

SELECT
  gName,
  GuildCount
FROM
  (
    SELECT
      IF(@LastCount <> 0 AND @LastCount <> grp.GuildCount, @flag := 0, @flag) AS flag,
      grp.gName,
      @LastCount := grp.GuildCount AS GuildCount
    FROM
      (
        SELECT
          @LastCount := 0,
          @flag := 1
      ) AS init,
      (
        SELECT
          gName,
          COUNT(Name) AS GuildCount
        FROM
          Guild
        GROUP BY
          gName
        ORDER BY
          GuildCount DESC
      ) AS grp
  ) AS derived
WHERE
  flag = 1
;
Run Code Online (Sandbox Code Playgroud)

init派生表仅仅是变量初始化,并grp提供了初始设定值合计的从高到低的顺序来使用我们的变量进行排序。

逻辑的主要部分位于实际使用变量的第二个嵌套级别。该@flag变量用于生成flag用于进一步过滤的列,用 标记需要包含在输出中的行,1其余的用标记0。它最初设置为 1,因为显然需要包括第一行。一旦遇到小于最大值的数字,它就会重置为 0。为此,使用了另一个变量@LastCount, 来存储前一行的计数值。

最外层查询仅过滤flag列上的嵌套集。

该解决方案可以在 Rexester进行测试。