SQL添加布尔列:标记各Unit最大Cycle为1其余为0的实现问题
嘿,我来帮你搞定这个问题!你的需求是给每个unit对应的最大cycle行标记1,其余行标记0,同时保留measure1和measure2的原始值——这确实不能用普通的GROUP BY,因为那样会丢失非聚合列的数据。
先看看你原来的SQL哪里出问题了:
GROUP BY unit会把每个unit的所有行合并成一行,这样你就看不到measure1、measure2以及其他cycle值的原始数据了,完全不符合你的需求;CASE WHEN max(cycle) then 1 end语法有问题,CASE需要一个布尔判断条件,你这里只写了max(cycle),数据库不知道要和什么做比较。
正确解决方案:使用窗口函数
窗口函数能在不聚合行的前提下,对每组(这里是每个unit)的数据进行排序和标记,完美匹配你的需求。下面给你两种常用的方案:
方案1:仅标记唯一的最大cycle行(如果有并列最大值,只选其中一行)
用ROW_NUMBER()窗口函数,它会给每个unit内的行按cycle降序编号,编号为1的就是最大cycle的行:
SELECT unit, cycle, measure1, measure2, CASE WHEN ROW_NUMBER() OVER (PARTITION BY unit ORDER BY cycle DESC) = 1 THEN 1 ELSE 0 END AS Failure FROM dbo.fd001 ORDER BY unit, cycle;
方案2:标记所有并列最大的cycle行(如果多个行的cycle是同一个最大值,都标记为1)
如果你的数据里可能存在同一个unit下有多个行的cycle值都是最大值,用RANK()函数会更合适,它会给并列最大值的行都分配排名1:
SELECT unit, cycle, measure1, measure2, CASE WHEN RANK() OVER (PARTITION BY unit ORDER BY cycle DESC) = 1 THEN 1 ELSE 0 END AS Failure FROM dbo.fd001 ORDER BY unit, cycle;
原理说明
这里的PARTITION BY unit是把数据按unit分组,ORDER BY cycle DESC让每个组内的行按cycle从大到小排序。窗口函数会为每组内的行计算对应的编号/排名,然后我们用CASE判断编号/排名是否为1,来标记Failure列——这样既保留了所有原始行的数据,又完成了你要的标记需求。
内容的提问来源于stack exchange,提问作者Sepide H
相关产品推荐
相关产品推荐

