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

PostgreSQL 13中如何对相同值的行进行分组且不破坏ORDER BY后的排序结果?

解决PostgreSQL中分组相同price行且保留原排序的问题

嘿,我看了你在PostgreSQL 13里遇到的分组问题,当前的查询用了grouping sets导致每个id对应两行数据,这显然不是你想要的结果。先拆解下你当前查询的问题:你用的grouping sets((tempId,price),(tempId,pemId,title,description))会生成两种分组行——一种是仅按tempId和price聚合的空字段汇总行,另一种是保留所有原字段的明细行,所以才会出现每个tempId重复的情况。

结合你的需求(对相同price的行进行分组,同时确保排序结果不被打乱),我给你两种常见场景的解决方案:

场景1:保留原id排序,给相同price的行标记分组

如果你希望结果完全按照原表的id顺序排列,同时给相同price的行加上分组标识,这里分两种情况:

全局分组(所有同price的行归为同一组)

这个方案会把所有price相同的行分配同一个组号,组号按该price第一次出现的id顺序生成,同时整体结果保持原id排序:

SELECT 
    id AS tempId,
    id AS pemId,
    title,
    description,
    price,
    DENSE_RANK() OVER (ORDER BY first_occurrence) AS price_group
FROM (
    SELECT 
        *,
        MIN(id) OVER (PARTITION BY price) AS first_occurrence
    FROM products
) AS sub
ORDER BY id;

连续分组(仅相邻同price的行归为一组)

如果你只想把连续出现的相同price行归为一组(比如测试数据里id2、3是一组,id5、6是另一组),可以用LAG()函数判断当前行和前一行的price是否一致:

SELECT 
    id AS tempId,
    id AS pemId,
    title,
    description,
    price,
    SUM(price_change) OVER (ORDER BY id) AS price_group
FROM (
    SELECT 
        *,
        CASE WHEN LAG(price) OVER (ORDER BY id) = price THEN 0 ELSE 1 END AS price_change
    FROM products
) AS sub
ORDER BY id;

场景2:分组折叠展示(汇总行+明细行,保留原排序)

如果你想要实现类似“分组标题+明细”的展示效果——每个price第一次出现时显示一行汇总信息,后面跟该price的所有明细行,同时整体保持原id的排序顺序,可以用UNION ALL结合窗口函数实现:

-- 先获取每个price的首次出现汇总行
SELECT 
    id AS tempId,
    NULL AS pemId,
    CONCAT('Price Group: ', price) AS title,
    'Group summary' AS description,
    price
FROM (
    SELECT 
        *,
        ROW_NUMBER() OVER (PARTITION BY price ORDER BY id) AS rn
    FROM products
) AS sub
WHERE rn = 1

UNION ALL

-- 再获取所有明细行
SELECT 
    id AS tempId,
    id AS pemId,
    title,
    description,
    price
FROM products

-- 排序确保汇总行在对应明细行之前,同时整体按原id顺序
ORDER BY 
    tempId,
    CASE WHEN pemId IS NULL THEN 0 ELSE 1 END;

这个查询的结果会是:

tempIdpemIdtitledescriptionprice
1Price Group: 2222Group summary2222
11testtest2222
2Price Group: 1111Group summary1111
22testtest21111
33test3test31111
4Price Group: 555Group summary555
44test3.2test3.2555
55test3.3test3.31111
66test4test4 desc1111

这样既实现了相同price的分组展示,又完全保留了原id的排序顺序,不会打乱你想要的排序效果。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.28 23:54:10