获取最大计数的行
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
子句,缺少表别名。以上是关于获取最大计数的行的主要内容,如果未能解决你的问题,请参考以下文章