基于Supp_No与Mat_No校验SQL表Val值一致性的需求
解决方案:基于多键生成Flag列
可以通过窗口函数实现需求,核心思路是按Supp_No分区,计算每个供应商下非空物料编号的唯一性、对应值的唯一性,再根据规则判断Flag。
通用SQL代码
SELECT ParNo, Supp_No, Mat_No, Val, CASE -- 规则3:Mat_No为NULL时标记NA WHEN Mat_No IS NULL THEN 'NA' -- 先判断当前供应商下是否存在多个不同的非空Mat_No WHEN (COUNT(DISTINCT CASE WHEN Mat_No IS NOT NULL THEN Mat_No END) OVER (PARTITION BY Supp_No)) > 1 THEN -- 规则1:所有非空Mat_No对应的Val全相同 → Yes CASE WHEN COUNT(DISTINCT CASE WHEN Mat_No IS NOT NULL THEN Val END) OVER (PARTITION BY Supp_No) = 1 THEN 'Yes' -- 规则2:Val不全相同 → No ELSE 'No' END -- 补充:当前供应商下只有一个非空Mat_No的情况(用户规则未明确,可按需调整) ELSE 'No' -- 或改为'NA'/'Yes',根据实际需求调整 END AS Flag FROM your_table_name;
代码解释
- 窗口函数分区:通过
PARTITION BY Supp_No将数据按供应商分组,确保每个分组内的计算仅针对当前供应商。 - 计数非空物料的唯一性:
COUNT(DISTINCT CASE WHEN Mat_No IS NOT NULL THEN Mat_No END)统计当前供应商下不同的非空物料编号数量,判断是否满足"Mat_No不同"的前提。 - 计数值的唯一性:
COUNT(DISTINCT CASE WHEN Mat_No IS NOT NULL THEN Val END)统计当前供应商下非空物料对应的值的唯一数量,判断是否全相同。 - CASE分支判断:按规则优先级依次判断,先处理
Mat_No为NULL的情况,再处理多物料的场景,最后补充单物料的情况。
测试示例
假设表数据如下:
| ParNo | Supp_No | Mat_No | Val |
|---|---|---|---|
| 1 | S1 | M1 | 100 |
| 2 | S1 | M2 | 100 |
| 3 | S1 | NULL | 200 |
| 4 | S2 | M3 | 200 |
| 5 | S2 | M4 | 300 |
| 6 | S3 | M5 | 500 |
执行代码后输出:
| ParNo | Supp_No | Mat_No | Val | Flag |
|---|---|---|---|---|
| 1 | S1 | M1 | 100 | Yes |
| 2 | S1 | M2 | 100 | Yes |
| 3 | S1 | NULL | 200 | NA |
| 4 | S2 | M3 | 200 | No |
| 5 | S2 | M4 | 300 | No |
| 6 | S3 | M5 | 500 | No |
注意事项
- 部分旧版本数据库可能不支持窗口函数中的
COUNT(DISTINCT)(如MySQL 5.x),此时可以先通过子查询分组计算每个供应商的物料数和值数,再关联回原表:
WITH supp_stats AS ( SELECT Supp_No, COUNT(DISTINCT Mat_No) AS distinct_mats, COUNT(DISTINCT Val) AS distinct_vals FROM your_table_name WHERE Mat_No IS NOT NULL GROUP BY Supp_No ) SELECT t.ParNo, t.Supp_No, t.Mat_No, t.Val, CASE WHEN t.Mat_No IS NULL THEN 'NA' WHEN s.distinct_mats > 1 THEN CASE WHEN s.distinct_vals = 1 THEN 'Yes' ELSE 'No' END ELSE 'No' END AS Flag FROM your_table_name t LEFT JOIN supp_stats s ON t.Supp_No = s.Supp_No;
内容的提问来源于stack exchange,提问作者T S Nandakumar
相关产品推荐
相关产品推荐

