如何基于DateTime及其他变量设置SQL变量并扩展replicate函数应用
问题2:扩展REPLICATE函数支持更多结果类型,生成ResultStatus
先明确从你的示例结果中反推的规则:
- 当同一个
Run+Test分组内有多种Result类型时:ResultStatus由所有类型的首字母组成,当前行的Result首字母大写,其余小写(比如Run1的三个结果对应Nft/nFt/nfT)。 - 当同一个
Run+Test分组内只有一种Result类型时:ResultStatus由n个该类型的首字母组成(n是分组内的测试数),当前行在分组内的排序位置对应的字母大写(比如Run2的两个Failed对应Ff/fF)。
要实现这个,我们可以结合窗口函数、REPLICATE、STUFF和字符串拼接来扩展逻辑,不管新增多少种Result类型都能自动适配:
完整SQL代码
WITH TestGroupInfo AS ( SELECT Run, Test, StartTime, Result, -- 给每个分组内的Result类型按首次出现时间排序,分配专属位置 DENSE_RANK() OVER ( PARTITION BY Run, Test ORDER BY MIN(StartTime) OVER (PARTITION BY Run, Test, Result) ) AS ResultPos, -- 分组内的不同Result类型总数 COUNT(DISTINCT Result) OVER (PARTITION BY Run, Test) AS ResultTypeCount, -- 分组内的总测试数 COUNT(*) OVER (PARTITION BY Run, Test) AS TotalTests, -- 分组内按StartTime排序的行号 ROW_NUMBER() OVER (PARTITION BY Run, Test ORDER BY StartTime) AS RowNum, -- 提取Result的首字母(小写) LOWER(LEFT(Result, 1)) AS ResultInitial FROM TestResults ) SELECT Run, Test, StartTime, Result, CASE -- 情况1:分组内只有一种Result类型,用REPLICATE生成重复字符串,替换对应位置为大写 WHEN ResultTypeCount = 1 THEN STUFF( REPLICATE(ResultInitial, TotalTests), RowNum, 1, UPPER(ResultInitial) ) -- 情况2:分组内有多种Result类型,先拼接所有类型的小写首字母,再替换当前类型的位置为大写 ELSE STUFF( ( SELECT STRING_AGG(t2.ResultInitial, '') FROM (SELECT DISTINCT ResultPos, ResultInitial FROM TestGroupInfo t2 WHERE t2.Run = t1.Run AND t2.Test = t1.Test) t2 ORDER BY t2.ResultPos ), t1.ResultPos, 1, UPPER(t1.ResultInitial) ) END AS ResultStatus FROM TestGroupInfo t1 ORDER BY Run, Test, StartTime;
扩展逻辑说明
- 处理单一Result类型:用
REPLICATE(ResultInitial, TotalTests)生成n个小写首字母的字符串,再用STUFF把当前行号对应的位置替换成大写——不管分组内有多少条测试,新增多少同类型结果,这个逻辑都能自动适配。 - 处理多种Result类型:先通过
STRING_AGG按Result类型的出现顺序拼接所有小写首字母,再用STUFF把当前Result对应的位置替换成大写——新增任何Result类型(比如新增Passed),只要首字母唯一,不需要修改代码就能自动加入ResultStatus的字符串中。
比如如果新增一条Run=1, Test=20, StartTime='2020-01-01 00:05', Result='Passed'的记录,ResultStatus会自动扩展为4位,对应Passed的行是nftP。
内容的提问来源于stack exchange,提问作者Japie07
相关产品推荐
相关产品推荐

