简体   繁体   English

在另一行之后查找一行

[英]Find a row after another row

The scope of this quesiton is SQL server 2016. 此问题的范围是SQL Server 2016。

I have a table with some temperature measurements in. I'm trying to create a CTE with the 3 rows: 我有一个带有一些温度测量值的表。我试图用3行创建一个CTE:

First row in the start of the process. 该过程开始的第一行。

Second row when a threshold temperature is met. 达到阈值温度时的第二行。

Third row when another threshold temperature is met, but must be after the second row (order by time) 满足另一个阈值温度的第三行,但必须在第二行之后(按时间排序)

This is my SQL so far. 到目前为止,这是我的SQL。 It IS working, but finding the third rows seems a bit clumsy. 它正在工作,但是找到第三行似乎有点笨拙。 Isn't there a smarter way to find it. 没有找到它的更聪明的方法。

declare 
   @ThresholdMinTemp int = 550,  @ThresholdCoolingTemp int = 250;

declare @TestData Table
(
  Time int,
  Temp_Front int, 
  Temp_Center int, 
  Temp_Back int
);


insert into @TestData 
values 
    (2, 26, 27, 27), 
    (102, 26, 27, 27), 
    (232, 148, 136, 130), 
    (309, 252, 245, 238), 
    (548, 549, 553, 550), 
    (550, 550, 553, 550), 
    (552, 551, 554, 551), 
    (555, 552, 555, 552), 
    (722, 387, 387, 374), 
    (963, 250, 251, 233), 
    (967, 248, 249, 231);

with CTE_ResultTable  as
(
    select ROW_NUMBER() over (order by time) RowNumber, "Description", Time, Temp_Front,  Temp_Center, Temp_Back from 
     (      
        select  top 1 'Start temp' "Description", * from @TestData   order by time
        union all   
        select  top 1 'ThresholdMinTemp' "Description", * from @TestData  where Temp_Front >= @ThresholdMinTemp and Temp_Center >= @ThresholdMinTemp and Temp_Back >= @ThresholdMinTemp order by time
        union all 
        select  top 1 'ThresholdCoolingTemp' "Description", * from @TestData where Temp_Front <= @ThresholdCoolingTemp and Temp_Center <= @ThresholdCoolingTemp and Temp_Back <= @ThresholdCoolingTemp  
        and time > (select  top 1 time from TestData1 where Temp_Front >= @ThresholdMinTemp and Temp_Center >= @ThresholdMinTemp and Temp_Back >= @ThresholdMinTemp order by time)
        order by time
     ) Dummy
)
select * from CTE_ResultTable

So in short given the above dataset, I need to find the first row (order by time) where all 3 sensors measures max 250 degrees, after all three have reached 550 degrees! 简而言之,鉴于上述数据集,我需要找到第一行(按时间顺序),在这三个传感器都达到550度之后,所有3个传感器都测量最大250度!

In my real dataset I have a ID (uniqueidentifier) so if needed it can just be added to the demo dataset. 在我的真实数据集中,我有一个ID(唯一标识符),因此如果需要,可以将其添加到演示数据集中。

If i understand correctly, this might be a "little" better; 如果我理解正确的话,这可能会更好。 it at least doesn't scan the table 3 times (only the once). 它至少不扫描表3次(仅扫描一次)。

WITH KPIs AS(
    SELECT *,
           CASE WHEN [Time] = MIN(Time) OVER () THEN 'Start Temp'
                WHEN Temp_Front >= @ThresholdMinTemp AND Temp_Center >= @ThresholdMinTemp AND Temp_Back >= @ThresholdMinTemp THEN 'ThresholdMinTemp' 
                WHEN Temp_Front <= @ThresholdCoolingTemp AND Temp_Center <= @ThresholdCoolingTemp AND Temp_Back <= @ThresholdCoolingTemp
                 AND COUNT(CASE WHEN Temp_Front >= @ThresholdMinTemp AND Temp_Center >= @ThresholdMinTemp AND Temp_Back >= @ThresholdMinTemp THEN 1 END) OVER (ORDER BY [Time] ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) > 1 THEN 'ThresholdCoolingTemp' END AS KPI
    FROM @TestData),
RNs AS (
    SELECT *,
           ROW_NUMBER() OVER (PARTITION BY KPI ORDER BY [time] ASC) AS RN
    FROM KPIs)
SELECT ROW_NUMBER() OVER (ORDER BY [Time]) AS RowNumber,
       KPI AS [Description],
       [Time],
       Temp_Front, Temp_Center, Temp_Back
FROM RNs
WHERE KPI IS NOT NULL
  AND RN = 1
ORDER BY RowNumber ASC;

This may help. 这可能会有所帮助。

declare @TestData Table
(
  Time int,
  Temp_Front int, 
  Temp_Center int, 
  Temp_Back int
);


insert into @TestData 
values 
    (2, 26, 27, 27), 
    (102, 26, 27, 27), 
    (232, 148, 136, 130), 
    (309, 252, 245, 238), 
    (548, 549, 553, 550), 
    (550, 550, 553, 550), 
    (552, 551, 554, 551), 
    (555, 552, 555, 552), 
    (722, 387, 387, 374), 
    (963, 250, 251, 233), 
    (967, 248, 249, 231);

WITH CTE_ResultTable (seq_no, Description, Time,Temp_Front, Temp_Center,Temp_Back)  
AS 

(

        select  top(1) 1 as seq_no, 'Start temp' "Description", Time,Temp_Front, Temp_Center, Temp_Back from @TestData   order by time
        union all   
        select  top(1) 2 as seq_no, 'ThresholdMinTemp' "Description", Time,Temp_Front, Temp_Center, Temp_Back from @TestData  where Temp_Front >= @ThresholdMinTemp and Temp_Center >= @ThresholdMinTemp and Temp_Back >= @ThresholdMinTemp order by time
        union all
        select  top(1) 3 as seq_no, 'ThresholdCoolingTemp' "Description",Time, Temp_Front, Temp_Center, Temp_Back from @TestData where Temp_Back <= @ThresholdCoolingTemp order by time desc


)
select * from CTE_ResultTable

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM