寻找首行满足三个温度值均大于首行对应值的SQL实现方案
优化实现:找到首行满足温度均大于基准值的记录
嘿,我来帮你简化这个查询!你之前用一堆变量的方式确实有点繁琐,咱们用几种更简洁的方法来实现你的需求,完全不需要额外变量:
首先先还原你的测试数据集:
declare @TestData Table ( Time int, Temp_Front int, Temp_Center int, Temp_Back int ); insert into @TestData values (2, 26, 27, 27), (3, 26, 28, 27), (4, 27, 28, 27), (5, 27, 28, 28);
你的需求是:找到按Time升序排列后,第一条满足三个温度字段都大于首行对应温度值的记录(首行基准值为:Temp_Front=26,Temp_Center=27,Temp_Back=27)。
方法1:子查询关联基准值
通过子查询获取首行的基准温度值,直接关联筛选后取第一条符合条件的记录:
SELECT TOP 1 td.* FROM @TestData td CROSS JOIN ( -- 获取首行的基准温度值 SELECT Temp_Front AS Base_Front, Temp_Center AS Base_Center, Temp_Back AS Base_Back FROM @TestData ORDER BY Time ASC OFFSET 0 ROWS FETCH NEXT 1 ROW ONLY ) base -- 筛选满足所有温度都大于基准值的记录 WHERE td.Temp_Front > base.Base_Front AND td.Temp_Center > base.Base_Center AND td.Temp_Back > base.Base_Back -- 按时间排序取第一条 ORDER BY td.Time ASC;
这个方法逻辑直观,通过OFFSET FETCH精准获取首行基准值,不需要额外变量存储,查询效率也很高。
方法2:窗口函数广播基准值
利用窗口函数FIRST_VALUE将首行的基准值附加到每一行数据中,再筛选符合条件的记录:
WITH DataWithBase AS ( SELECT *, -- 按Time排序,获取首行的温度值作为基准 FIRST_VALUE(Temp_Front) OVER (ORDER BY Time ASC) AS Base_Front, FIRST_VALUE(Temp_Center) OVER (ORDER BY Time ASC) AS Base_Center, FIRST_VALUE(Temp_Back) OVER (ORDER BY Time ASC) AS Base_Back FROM @TestData ) SELECT TOP 1 * FROM DataWithBase WHERE Temp_Front > Base_Front AND Temp_Center > Base_Center AND Temp_Back > Base_Back ORDER BY Time ASC;
这种方法的优势是逻辑连贯,不需要额外的关联操作,窗口函数会自动帮我们把基准值映射到所有行,后续筛选和取第一条的操作非常简洁。
两种方法最终都会返回Time=5的那条记录,完全符合你的需求,而且都避免了使用大量变量的繁琐操作。
内容的提问来源于stack exchange,提问作者Jens Borrisholt
相关产品推荐
相关产品推荐

