获取最大计数的行

Posted

技术标签:

【中文标题】获取最大计数的行【英文标题】:Get rows with maximum count 【发布时间】:2014-10-21 16:53:36 【问题描述】:

我需要执行查询以获取孩子们最喜欢的糖果,这就是我得到的:

SELECT COUNT(*) as counts,candies.name
FROM candies 
INNER JOIN kid_candy ON kid_candy.candy_id = candies.id
INNER JOIN kids ON kids.id = kid_candy.kid_id
GROUP BY candies.name

会返回:

counts  | name
--------+---------
  3     | snowbear
  3     | whiterabbit
  2     | lollipop

我只想看到

counts  | name
--------+---------
  3     | snowbear
  3     | whiterabbit

那么我的查询应该是什么?

【问题讨论】:

【参考方案1】:

所以,首先让我们获取每个糖果名称的计数 (tmp_table),然后获取所有糖果的最大计数 (max_cnt),最后将它们放在一起并从 tmp_table 获取有计数的糖果等于max(counts) from max_cnt table...

 with tmp_table AS (
    select COUNT(*) as counts,candies.name as c_name
    from candies 
    INNER JOIN kid_candy ON kid_candy.candy_id = candies.id
    INNER JOIN kids ON kids.id = kid_candy.kid_id
    GROUP BY candies.name        
 ), 
 max_cnt AS (
    SELECT max(counts) as max_count from tmp_table
 )
 SELECT counts, c_name as candies
 FROM tmp_table 
 JOIN max_cnt on max_count = counts

【讨论】:

【参考方案2】:

假设孩子和糖果之间存在经典的 n:m 关系,如下所述:

How to implement a many-to-many relationship in PostgreSQL?

您应该在问题中提供此类详细信息。

SELECT c.id, kc.counts, c.name
FROM  (
   SELECT candy_id AS id, count(*) AS counts
        , rank() OVER (ORDER BY count(*) DESC) AS rnk
   FROM   kid_candy
   GROUP  BY 1
   ) kc
JOIN   candies c USING (id)
WHERE  kc.rnk = 1;

这应该比使用两个 CTE 和不必要的连接的查询快得多。

要点

candies.name 分组可能是错误的(而且成本更高)。该名称可能不是唯一的。为此使用主键列,可能是candies.id

假设参照完整性,我们根本不需要加入表 kids

由于我们需要检查整个表,所以先聚合然后加入糖果以获得name之后更快.

您可以在聚合函数上运行窗口函数:

Get the distinct sum of a joined table column

【讨论】:

【参考方案3】:

试试这个

SELECT * FROM
(
   SELECT COUNT(*) AS Counts,candies.name FROM candies 
     INNER JOIN kid_candy ON kid_candy.candy_id = candies.id
     INNER JOIN kids ON kids.id = kid_candy.kid_id
   GROUP BY candies.name
 ) T1 JOIN
SELECT MAX(counts) MaxCount FROM
(
   SELECT COUNT(*) AS Counts,candies.name FROM candies 
      INNER JOIN kid_candy ON kid_candy.candy_id = candies.id
      INNER JOIN kids ON kids.id = kid_candy.kid_id
   GROUP BY candies.name
) T1 ON T1.counts =T2.MaxCount

【讨论】:

【参考方案4】:

做一个子选择

Select max(counts) 
    (select COUNT(*) as counts,candies.name from candies 
INNER JOIN kid_candy ON kid_candy.candy_id = candies.id
INNER JOIN kids ON kids.id = kid_candy.kid_id
GROUP BY candies.name)

【讨论】:

这只会得到最大计数,而不是所需的结果,但语法错误:缺少FROM 子句,缺少表别名。

以上是关于获取最大计数的行的主要内容,如果未能解决你的问题,请参考以下文章

sql如何求分组计数之后计数的最大值

Hive 查询以获取最大计数

用于获取不同日期以及唯一计数最大值的大查询

获取mongodb中最大计数的字段名称

获取MySql中两列最大值的行

获取 SQL Server 中包含最大值的行