SQL - 获取最大值

SQL - getting max value

下面的查询给出了计数大于 70 的结果。

SELECT books.name, COUNT(library.staff)
FROM (library INNER JOIN books
ON library.staff = books.id)
GROUP BY library.staff,books.id
HAVING COUNT(library.staff) > 70;

如何修改查询以获得 最大 计数的结果?

一种方法是order bylimit:

SELECT b.name, COUNT(l.staff) as cnt
FROM library l INNER JOIN
     books b
     ON l.staff = b.id
GROUP BY l.staff, b.name
ORDER BY cnt DESC
LIMIT 1;

您按两列分组,但 select 中只有一列,我觉得很奇怪。但是,如果查询有效,那么它只是在查找重复项。

你可以这样做

SELECT books.name, COUNT(library.staff)
FROM (library INNER JOIN books
ON library.staff = books.id)
GROUP BY library.staff,books.id
HAVING COUNT(library.staff) = (select max(library.staff) from library);

您可以使用 ORDER BY() DESC 和 LIMIT 1

SELECT books.name, COUNT(library.staff)
FROM (library INNER JOIN books
ON library.staff = books.id)
GROUP BY library.staff,books.id
ORDER BY COUNT(library.staff) DESC
LIMIT 1

真的吗?

您加入 library.staff = books.id。这是一个令人惊讶的命名约定。一本书的ID等于图书馆的“职员”?您应该提供 table 定义和一些解释...

为了这个答案的目的,我们假设这是正确的。

审核查询

除了使用 table 别名以提高可读性之外,您还可以在几个地方进行简化:

SELECT b.id, b.name, count(*) AS ct
FROM   library l
JOIN   books b ON b.id = l.staff 
GROUP  BY b.id  -- l.staff -- redundant
HAVING count(*) > 70;
  • 因为你是在b.id = l.staff上加入的,l.staff肯定是NOT NULL,所以用count(*)比较快一点做同样的事情(count 的单独实现,它只计算行而不查看列)。

  • GROUP BY b.id 在这种情况下没有 l.staff 也一样。

  • 但由于您是按 b.id 分组,而不是按 b.name 分组,因此可能存在重复名称,我们只能通过在结果中添加 id 来区分- 除非 name 是唯一的,您没有指定。

更快的查询

假设books.id是主键这似乎是合理的:

SELECT b.id, b.name, l.ct
FROM   books b 
JOIN  (
   SELECT staff AS id, count(*) AS ct 
   FROM   library 
   GROUP  BY 1
   ) l USING (id)
HAVING count(*) > 70;

阅读整个 table 或其中的大部分内容,通常先聚合然后加入要快得多。

  • Aggregate a single column in query with many columns

EXPLAIN ANALYZE 测试。

回答

要获得最大计数的结果,ORDER BY count(*) DESC LIMIT 1 与提供的其他答案一样通常是最快的选择 - 获得 一个 获胜者.

获得所有位获奖者:

SELECT b.id, b.name, l.ct
FROM   books b 
JOIN  (
   SELECT staff AS id, count(*) AS ct
        , rank() OVER (ORDER BY count(*) DESC) AS rnk
   FROM   library 
   GROUP  BY 1
   ) l USING (id)
WHERE  l.rnk = 1;

在这里使用window function rank()(不是row_number())。
请注意,您可以在单个 SELECT:

中组合聚合函数和 window 函数
  • Get the distinct sum of a joined table column