如何高效实现基于Zone分组的SQL车辆状态统计表格转换
高效实现车辆状态聚合统计的SQL写法
原表结构与数据
现有table_a表结构及数据如下:
| Zone | vehicle_name | vehicle_status |
|---|---|---|
| A | BusA1 | Start |
| A | BusA2 | Start |
| A | BusA3 | Stopped |
| B | BoatB1 | Ready |
| B | BoatB2 | Stopped |
| B | BoatB3 | Start |
| C | CarC1 | Ready |
| C | CarC2 | Ready |
| C | CarC3 | Stopped |
目标需求
需要生成如下结构的聚合统计表格,按Zone分组统计该区域的总车辆数、各状态车辆数:
| Zone | no_of_vehicle | no_of_start | no_of_ready | no_of_stopped |
|---|---|---|---|---|
| A | 3 | 2 | 0 | 1 |
| B | 3 | 1 | 1 | 1 |
| C | 3 | 0 | 2 | 1 |
高效SQL实现
以下是最高效的写法,通过一次表扫描+分组条件聚合完成所有统计,避免多次查询或关联操作:
SELECT Zone, COUNT(*) AS no_of_vehicle, SUM(CASE WHEN vehicle_status = 'Start' THEN 1 ELSE 0 END) AS no_of_start, SUM(CASE WHEN vehicle_status = 'Ready' THEN 1 ELSE 0 END) AS no_of_ready, SUM(CASE WHEN vehicle_status = 'Stopped' THEN 1 ELSE 0 END) AS no_of_stopped FROM table_a GROUP BY Zone;
写法说明
GROUP BY Zone:按区域分组,替代DISTINCT更适合分组统计场景,逻辑清晰且性能更优COUNT(*):直接统计每组总记录数,即该区域总车辆数,效率最高SUM(CASE...):通过条件聚合一次性统计各状态车辆数,仅需扫描表一次,比多次子查询或JOIN的性能好很多
如果使用MySQL,也可以用IF函数简化CASE语句,写法如下:
SELECT Zone, COUNT(*) AS no_of_vehicle, SUM(IF(vehicle_status = 'Start', 1, 0)) AS no_of_start, SUM(IF(vehicle_status = 'Ready', 1, 0)) AS no_of_ready, SUM(IF(vehicle_status = 'Stopped', 1, 0)) AS no_of_stopped FROM table_a GROUP BY Zone;
两种写法性能基本一致,选择符合你使用的SQL方言即可。
内容的提问来源于stack exchange,提问作者user19192927
相关产品推荐
相关产品推荐

