如何按ProformaInvoiceNum分组生成Main Process列的SQL解决方案
SQL实现分组标记主流程需求
需求说明
需要为包含ProcessName和ProformaInvoiceNum的数据集新增Main Process列,规则如下:
- 同一
ProformaInvoiceNum分组内存在TOP CUTTING时,该组所有行的Main Process取值为TOP CUTTING - 分组内无
TOP CUTTING但存在Cutting时,取值为Cutting
原始数据
| ProcessName | ProformaInvoiceNum |
|---|---|
| TOP CUTTING | SHE/PBK/23/10001.1 |
| Back Cutting | SHE/PBK/23/10001.1 |
| LINING CUTTING | SHE/PBK/23/10001.1 |
| Cutting | SHE/SHR/22/10155.1 |
| TOP CUTTING | SHE/REHRM/22/10026.4 |
| Cutting | SHE/REHRM/22/10047.4 |
| Recutting | SHE/REHRM/22/10047.4 |
| TOP CUTTING | SHE/SHR/22/10308.1 |
| Cutting | SHE/SHR/22/10308.1 |
目标效果
| ProcessName | ProformaInvoiceNum | Main Process |
|---|---|---|
| TOP CUTTING | SHE/PBK/23/10001.1 | TOP CUTTING |
| Back Cutting | SHE/PBK/23/10001.1 | TOP CUTTING |
| LINING CUTTING | SHE/PBK/23/10001.1 | TOP CUTTING |
| Cutting | SHE/SHR/22/10155.1 | Cutting |
| TOP CUTTING | SHE/REHRM/22/10026.4 | TOP CUTTING |
| Cutting | SHE/REHRM/22/10047.4 | Cutting |
| Recutting | SHE/REHRM/22/10047.4 | Cutting |
| TOP CUTTING | SHE/SHR/22/10308.1 | TOP CUTTING |
| Cutting | SHE/SHR/22/10308.1 | TOP CUTTING |
SQL实现方案
方法一:窗口函数(推荐,兼容MySQL 8.0+、PostgreSQL、SQL Server等主流数据库)
SELECT ProcessName, ProformaInvoiceNum, CASE WHEN MAX(CASE WHEN ProcessName = 'TOP CUTTING' THEN 1 ELSE 0 END) OVER (PARTITION BY ProformaInvoiceNum) = 1 THEN 'TOP CUTTING' WHEN MAX(CASE WHEN ProcessName = 'Cutting' THEN 1 ELSE 0 END) OVER (PARTITION BY ProformaInvoiceNum) = 1 THEN 'Cutting' ELSE NULL -- 可根据需求补充无匹配时的默认值 END AS `Main Process` FROM your_table_name;
方法二:子查询分组预处理(兼容低版本数据库)
WITH process_groups AS ( SELECT ProformaInvoiceNum, CASE WHEN EXISTS (SELECT 1 FROM your_table_name t2 WHERE t2.ProformaInvoiceNum = t1.ProformaInvoiceNum AND t2.ProcessName = 'TOP CUTTING') THEN 'TOP CUTTING' WHEN EXISTS (SELECT 1 FROM your_table_name t2 WHERE t2.ProformaInvoiceNum = t1.ProformaInvoiceNum AND t2.ProcessName = 'Cutting') THEN 'Cutting' ELSE NULL END AS main_process FROM your_table_name t1 GROUP BY ProformaInvoiceNum ) SELECT t.ProcessName, t.ProformaInvoiceNum, pg.main_process AS `Main Process` FROM your_table_name t LEFT JOIN process_groups pg ON t.ProformaInvoiceNum = pg.ProformaInvoiceNum;
方案说明
- 窗口函数方法:通过
PARTITION BY按发票号分组,用MAX()函数判断分组内是否存在指定流程,再通过CASE返回对应主流程,无需额外关联,性能更优。 - 子查询方法:先对每个发票号分组判断主流程,再通过左关联将主流程值映射到原表每一行,兼容不支持窗口函数的旧版数据库。
内容的提问来源于stack exchange,提问作者Ankur Singh Bhandari
相关产品推荐
相关产品推荐

