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

PostgreSQL中如何按路线获取最短配送时间对应的数据行

在PostgreSQL中按路线编码筛选最短配送时间的行

这需求挺常见的,我给你整理几种PostgreSQL里的实现方案,你可以根据实际场景选:

先把你的示例表结构和数据用SQL还原出来,方便测试:

CREATE TABLE deliveries (
    route_code VARCHAR(10),
    name VARCHAR(50),
    time TIME
);

INSERT INTO deliveries VALUES
('A', 'McDonald''s', '05:30'),
('A', 'Arby''s', '05:45'),
('A', 'Burger King', '06:00'),
('A', 'Wendy''s', '06:30'),
('B', 'Arby''s', '07:45'),
('B', 'Arby''s', '07:45'),
('B', 'Burger King', '08:00');

方案一:窗口函数(推荐,灵活度高)

窗口函数是PostgreSQL处理这类分组排名需求的利器,这里推荐用RANK()或者ROW_NUMBER(),区别在于如何处理同组内最短时间重复的情况:

用RANK()保留所有最短时间的行

如果同一路线里有多个配送点的时间都是最短的(比如路线B里的两个Arby's),这个方案会把这些行都返回:

SELECT route_code, name, time
FROM (
    SELECT 
        route_code, 
        name, 
        time,
        -- 按路线分组,按时间升序排名,最短时间排第1
        RANK() OVER (PARTITION BY route_code ORDER BY time ASC) AS rank
    FROM deliveries
) ranked_deliveries
WHERE rank = 1;

用ROW_NUMBER()只返回每组一行

如果不管有没有重复,你只想每组取一行(系统会随机选一个最短时间的行),就用ROW_NUMBER()替换RANK():

SELECT route_code, name, time
FROM (
    SELECT 
        route_code, 
        name, 
        time,
        ROW_NUMBER() OVER (PARTITION BY route_code ORDER BY time ASC) AS row_num
    FROM deliveries
) numbered_deliveries
WHERE row_num = 1;

方案二:子查询关联(逻辑直观)

如果你对窗口函数不太熟悉,也可以用子查询先找出每个路线的最短时间,再关联原表获取完整行数据,同样会保留所有最短时间的行:

SELECT d.route_code, d.name, d.time
FROM deliveries d
INNER JOIN (
    -- 先按路线分组,计算每组的最短时间
    SELECT route_code, MIN(time) AS min_time
    FROM deliveries
    GROUP BY route_code
) route_min_times 
ON d.route_code = route_min_times.route_code 
AND d.time = route_min_times.min_time;

注意事项

如果你的TIME字段是字符串类型(比如示例里的...),一定要先转换成TIME类型再排序,否则会出现排序错误。转换方式可以用:

CAST(time AS TIME)
-- 或者PostgreSQL特有的简写
time::TIME

比如修改窗口函数里的排序部分:

ORDER BY CAST(time AS TIME) ASC

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 08:27:49