Найти строку за другой строкой - PullRequest
0 голосов
/ 02 мая 2018

Сфера действия этого задания - SQL Server 2016.

У меня есть таблица с некоторыми измерениями температуры. Я пытаюсь создать CTE с 3 строками:

Первая строка в начале процесса.

Второй ряд при достижении пороговой температуры.

Третий ряд при достижении другой пороговой температуры, но должен быть после второго ряда (порядок по времени)

Пока это мой SQL. Это работает, но поиск третьих строк кажется немного неуклюжим. Разве нет более умного способа найти это.

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

Итак, вкратце, учитывая приведенный выше набор данных, мне нужно найти первый ряд (порядок по времени), где все 3 датчика измеряют максимум 250 градусов, после того как все три достигли 550 градусов!

В моем реальном наборе данных у меня есть идентификатор (uniqueidentifier), поэтому при необходимости его можно просто добавить в набор демонстрационных данных.

Ответы [ 2 ]

0 голосов
/ 02 мая 2018

Это может помочь.

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
0 голосов
/ 02 мая 2018

Если я правильно понимаю, это может быть немного лучше; по крайней мере, он не сканирует таблицу 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;
...