SQL按指定列分组并对某列连续值求和的技术实现问询
解决方案:连续相同SurfaceType的TotalChain求和
看起来你需要对连续相同SurfaceType的路段进行TotalChain的累加求和,而不是单纯按SurfaceType分组(那样会把所有同类型路段合并,不管是否连续)。结合你已经按FromChain排序的数据集,我来帮你实现这个逻辑:
完整SQL查询
WITH ranked_segments AS ( SELECT ThanaId, RoadId, TotalChain, FromChain, ToChain, SurfaceType, -- 判断当前行是否与上一行的SurfaceType不同,不同则标记为新分组起点 CASE WHEN LAG(SurfaceType) OVER (PARTITION BY ThanaId, RoadId ORDER BY FromChain) != SurfaceType THEN 1 ELSE 0 END AS is_new_group FROM Segment WHERE ThanaId = (SELECT MIN(ThanaId) FROM RdLineDiagTemp) AND RoadId = (SELECT MIN(RoadId) FROM RdLineDiagTemp) ), grouped_segments AS ( SELECT *, -- 累计求和生成分组ID,连续相同SurfaceType的行会拥有同一个ID SUM(is_new_group) OVER (PARTITION BY ThanaId, RoadId ORDER BY FromChain) AS group_id FROM ranked_segments ) SELECT ThanaId, RoadId, SUM(TotalChain) AS TotalChainSum, -- 连续路段的总长度 MIN(FromChain) AS StartChain, -- 该连续段的起始链号 MAX(ToChain) AS EndChain, -- 该连续段的结束链号 SurfaceType FROM grouped_segments GROUP BY ThanaId, RoadId, group_id, SurfaceType ORDER BY StartChain;
逻辑拆解
ranked_segments公共表表达式(CTE):- 用
LAG()窗口函数获取当前行的上一行SurfaceType - 通过
CASE语句标记当前行是否是新分组的起点(当SurfaceType与上一行不同时标记为1)
- 用
grouped_segmentsCTE:- 对
is_new_group进行累计求和,生成group_id——连续相同SurfaceType的行会被分配同一个group_id,这样就把连续的同类型路段归为一组了
- 对
最终聚合查询:
- 按
ThanaId、RoadId、group_id和SurfaceType分组 - 求和
TotalChain得到连续路段的总长度,同时取该段的起始和结束链号,方便你查看连续段的范围
- 按
示例结果
针对你给出的前3条BC类型数据,执行后会得到一条合并结果:
| ThanaId | RoadId | TotalChainSum | StartChain | EndChain | SurfaceType |
|---|---|---|---|---|---|
| 54701 | 1368 | 5850 | 0 | 5850 | BC |
内容的提问来源于stack exchange,提问作者Tousif Md. Amin Faisal
相关产品推荐
相关产品推荐

