You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何获取GROUP BY后各(week,year,device_id)分组中my_number计数最大的行?

解决PostgreSQL分组取计数最高行的问题

表结构

PostgreSQL表public.tmch的结构如下:

CREATE TABLE IF NOT EXISTS public.tmch (
    id bigserial NOT NULL,
    year integer,
    week integer,
    my_number integer,
    device_id bigint,
    CONSTRAINT tmch_pkey PRIMARY KEY (id)
);

示例数据

1716446 2024    37  13  2
1716447 2024    37  13  2
1716448 2024    37  0   3
1716449 2024    37  11  4
1716450 2024    37  12  4
1716451 2024    37  0   6
1716452 2024    37  0   6
1716453 2024    37  0   6
1716454 2024    37  1   6
1716455 2024    37  1   6
1716456 2024    37  9   7

现有统计查询

已使用以下SQL统计每个(week, year, device_id)分组中my_number的出现次数:

select count(my_number) c, my_number, device_id, year, week from tmch
group by my_number, device_id, year, week
order by device_id asc, c desc

基于更大样本的查询结果:

6   16  2   2024    37
4   17  2   2024    37
4   15  2   2024    37
2   13  2   2024    37
1   2   2   2024    37
8   15  3   2024    37
6   16  3   2024    37
5   14  3   2024    37
3   20  3   2024    37  
3   18  3   2024    37
3   19  3   2024    37
1   8   3   2024    37

需求

仅获取每个(week, year, device_id)分组中my_number计数最高的行,期望结果:

6   16  2   2024    37  -- my_number=16在device_id=2、2024年第37周出现6次,为该分组最高
8   15  3   2024    37  -- my_number=15在device_id=3、2024年第37周出现8次,为该分组最高

解决方案

使用row_number()窗口函数,核心是按year, week, device_id分区,再按计数c降序排序,取排序后行号为1的记录:

WITH counted AS (
    SELECT 
        count(my_number) c, 
        my_number, 
        device_id, 
        year, 
        week,
        row_number() OVER (PARTITION BY year, week, device_id ORDER BY count(my_number) DESC) AS rn
    FROM tmch
    GROUP BY my_number, device_id, year, week
)
SELECT c, my_number, device_id, year, week
FROM counted
WHERE rn = 1
ORDER BY device_id;

补充说明

如果同一个分组中存在多个my_number计数相同且均为最高的情况,上述SQL只会返回其中一条。若要保留所有并列最高的记录,将row_number()替换为rank()即可:

WITH counted AS (
    SELECT 
        count(my_number) c, 
        my_number, 
        device_id, 
        year, 
        week,
        rank() OVER (PARTITION BY year, week, device_id ORDER BY count(my_number) DESC) AS rn
    FROM tmch
    GROUP BY my_number, device_id, year, week
)
SELECT c, my_number, device_id, year, week
FROM counted
WHERE rn = 1
ORDER BY device_id;

内容的提问来源于stack exchange,提问作者Tigu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 09:25:01