如何使用SQL GROUP BY选取分组后的前1组或前10组所有记录?
如何查询分组后的前N组所有记录
我有一张包含COUNTRY, STATE, CITY, NAME列的表,按COUNTRY, STATE, CITY进行分组(分组规则:COUNTRY、STATE、CITY字段值完全相同的记录为一组)。请问如何编写SQL查询,返回前1组或前10组的所有记录?
示例表数据
| id | COUNTRY | STATE | CITY | NAME |
|---|---|---|---|---|
| 1 | US | CA | SF | Adam |
| 2 | US | CA | SF | Ben |
| 3 | US | TX | Austin | Carry |
| 4 | US | TX | Houston | Don |
预期返回结果(前1组)
| id | COUNTRY | STATE | CITY | NAME |
|---|---|---|---|---|
| 1 | US | CA | SF | Adam |
| 2 | US | CA | SF | Ben |
解决方案
核心思路是先给每个分组分配唯一编号,再筛选出编号≤目标数量的所有记录。以下是通用实现方式(适用于支持窗口函数的数据库:MySQL 8.0+、PostgreSQL、SQL Server等):
1. 返回前1组的所有记录
SELECT t.id, t.COUNTRY, t.STATE, t.CITY, t.NAME FROM ( SELECT *, DENSE_RANK() OVER (ORDER BY COUNTRY, STATE, CITY) AS group_rank FROM your_table_name ) t WHERE t.group_rank = 1;
2. 返回前10组的所有记录
只需修改WHERE条件的数值即可:
SELECT t.id, t.COUNTRY, t.STATE, t.CITY, t.NAME FROM ( SELECT *, DENSE_RANK() OVER (ORDER BY COUNTRY, STATE, CITY) AS group_rank FROM your_table_name ) t WHERE t.group_rank <= 10;
补充说明
- 使用
DENSE_RANK()可以保证字段完全一致的分组获得相同编号,避免因分组内记录数导致编号跳跃。 - 若需要按分组的记录数排序(比如优先返回记录最多的组),可以调整窗口函数的排序规则,示例代码如下:
SELECT t.id, t.COUNTRY, t.STATE, t.CITY, t.NAME FROM ( SELECT a.*, DENSE_RANK() OVER (ORDER BY b.group_count DESC) AS group_rank FROM your_table_name a JOIN ( SELECT COUNTRY, STATE, CITY, COUNT(*) AS group_count FROM your_table_name GROUP BY COUNTRY, STATE, CITY ) b ON a.COUNTRY = b.COUNTRY AND a.STATE = b.STATE AND a.CITY = b.CITY ) t WHERE t.group_rank <= 10;
内容的提问来源于stack exchange,提问作者topcan5
相关产品推荐
相关产品推荐

