如何在T-SQL中基于多列实现条件计数(连续座位分组统计)
解决T-SQL中连续剧院座位的分组统计问题
这个需求本质是识别同场次、同区域、同行内的连续座位段,然后统计每个连续段的座位数。单独用CASE语句确实很难处理这种连续分组的逻辑,我们可以借助T-SQL的窗口函数来优雅解决。
解决方案思路
核心是给每一组连续座位分配一个唯一的组ID,然后基于这个组ID进行聚合统计:
- 先按
perf_no、section、row和seat排序,保证座位是按顺序排列的; - 使用
LAG()函数获取当前座位的前一个座位号,判断是否连续(差值为1); - 通过累计求和生成组ID,每遇到不连续的座位就开启新的组;
- 最后按组ID分组统计每个连续段的座位数。
完整T-SQL代码
WITH SeatGroups AS ( SELECT perf_no, section, row AS seat_row, seat, -- 标记是否为新组的起点:如果前一个座位不存在,或差值≠1,则标记为1,否则0 CASE WHEN LAG(seat) OVER (PARTITION BY perf_no, section, row ORDER BY seat) IS NULL THEN 1 WHEN seat - LAG(seat) OVER (PARTITION BY perf_no, section, row ORDER BY seat) <> 1 THEN 1 ELSE 0 END AS NewGroupFlag, -- 生成组ID:累计求和NewGroupFlag,同一连续组的ID相同 SUM(CASE WHEN LAG(seat) OVER (PARTITION BY perf_no, section, row ORDER BY seat) IS NULL THEN 1 WHEN seat - LAG(seat) OVER (PARTITION BY perf_no, section, row ORDER BY seat) <> 1 THEN 1 ELSE 0 END) OVER (PARTITION BY perf_no, section, row ORDER BY seat) AS GroupID FROM YourSeatTable -- 替换成你的实际表名 ) SELECT perf_no, section, seat_row, COUNT(*) AS total FROM SeatGroups GROUP BY perf_no, section, seat_row, GroupID ORDER BY perf_no, section, seat_row, MIN(seat); -- 按座位号升序排列结果
代码解释
PARTITION BY perf_no, section, row:确保我们只在同场次、同区域、同行内进行连续判断;LAG(seat) OVER (...):获取当前座位的前一个座位值,用来判断是否连续;NewGroupFlag:标记每个连续组的起点,当遇到第一个座位或不连续的座位时,标记为1;GroupID:通过累计求和NewGroupFlag,让同一连续组的所有行拥有相同的ID;- 最后分组统计时,按
GroupID聚合就能得到每个连续座位段的数量。
测试结果
用你提供的测试数据执行这段代码,会得到和你示例完全一致的输出:
| perf_no | section | seat_row | total |
|---|---|---|---|
| 7128 | 6 | A | 2 |
| 7128 | 6 | A | 1 |
| 7128 | 6 | A | 1 |
| 7128 | 6 | A | 1 |
| 7129 | 6 | A | 1 |
| 7129 | 6 | A | 2 |
| 7129 | 6 | A | 1 |
| 7129 | 8 | B | 2 |
内容的提问来源于stack exchange,提问作者Impresario
相关产品推荐
相关产品推荐

