Найдите первую строку, где все три значения увеличились - PullRequest
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), 
    (3, 26, 28, 27), 
    (4, 27, 28, 27), 
    (5, 27, 28, 28);


select Time ,
  Temp_Front , 
  Temp_Center , 
  Temp_Back   from @TestData

Мне нужно найти первую строку, где все три значения Temp больше значений temp первой строки.

Итак, Temp_Front> 26, Temp_centre> 27, Temp_back> 27.

Я много чего перепробовал и всегда получаю много переменных. И много беспорядка.

Я не буду запятнать картину этим. Так что я просто включил проблему и набор данных.

Ответы [ 6 ]

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

Извините за поздний ответ. Вы можете использовать это:

;with [min] as (
    select top 1 
        [Time], [Temp_Front], [Temp_Center], [Temp_Back] 
    from
        @TestData 
    order  by 
         [Time] asc     
)
select top 1 
    [t].[Time], [t].[Temp_Front], [t].[Temp_Center], [t].[Temp_Back] 
from 
    @TestData   as [t]
cross join
    [min]       as [m]
where 
        ([t].[Time]         <>  [m].[Time])
    and [t].[Temp_Front]    >   [m].[Temp_Front]            
    and [t].[Temp_Center]   >   [m].[Temp_Center]
    and [t].[Temp_Back]     >   [m].[Temp_Back]
order by [Time] asc;

Полный запрос на тестирование: https://pastebin.com/3Hx33SfX

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

Интересно. Я хотел бы подойти к этому как:

with first_row as (
      select top (1) td.*
      from @testdata td
      order by time
     )
select top (1) td.*
from @testdata td cross join
     first_row fr
where td.temp_front > fr.temp_front and
      td.temp_center > fr.temp_center and
      td.temp_back > fr.temp_back
order by time asc;

Я не считаю, что оконные функции особенно полезны для этой проблемы.

Если вы используете оконные функции:

select top (1) td.*
from (select td.*,
             first_value(temp_front) over (order by time) as fr_temp_front,
             first_value(temp_center) over (order by time) as fr_temp_center,
             first_value(temp_back) over (order by time) as fr_temp_back
      from @testdata td
     ) td
where td.temp_front > fr_temp_front and
      td.temp_center > fr_temp_center and
      td.temp_back > fr_temp_back
order by time asc;
0 голосов
/ 02 мая 2018

Вот решение с использованием цикла:

declare @minrow int = (select min(time) from @testdata)
declare @iterator int = @minrow+1
declare @tempfront varchar(max)
declare @tempcenter varchar(max)
declare @tempback varchar(max)
declare @originaltempfront varchar(max)=(select  temp_front from  @testdata where time=@minrow)
declare @originaltempcenter varchar(max)=(select  temp_center from  @testdata where time=@minrow)
declare @originaltempback varchar(max) =(select  temp_back from  @testdata where time=@minrow)

while @iterator<= (select max(time) from @testdata)
begin
select @tempfront= temp_front from  @testdata where time=@iterator
select @tempcenter= temp_center from  @testdata where time=@iterator
select @tempback= temp_back from  @testdata where time=@iterator

if exists(select 1 from @testdata where @tempfront>@originaltempfront and @tempback>@originaltempback
and @tempcenter>@originaltempcenter and time=@iterator)
select * from @testdata where @tempfront>@originaltempfront and @tempback>@originaltempback
and @tempcenter>@originaltempcenter and time=@iterator
if @@rowcount <> 0 break

set @iterator=@iterator+1
end  
0 голосов
/ 02 мая 2018

Если я правильно понимаю, вы также можете использовать sum из temp значения

with cte as (
    select *, (select sum(temp_values) 
               from (values (Temp_Front), (Temp_center), (Temp_back))a(temp_values)) as Maxnum
    from  @TestData t
)

select * 
from cte c
where Maxnum = (select MAX(Maxnum) from cte);
0 голосов
/ 02 мая 2018

Рассчитать номера строк и использовать условное агрегирование, чтобы получить значения в первой строке. Затем это можно использовать для сравнения, чтобы получить первый такой ряд, который соответствует критериям, указанным с использованием TOP и ORDER BY.

with first_row as 
(
  select t.*, row_number() over(order by time) as rnum from @TestData t
)
select top 1 Time, Temp_Front, Temp_Center, Temp_Back
from 
    (
        select f.*, 
                max(case when rnum=1 then Temp_Front end) over() as first_tempfront,
                max(case when rnum=1 then Temp_Center end) over() as first_tempcenter,
                max(case when rnum=1 then Temp_Back end) over() as first_tempback
        from first_row f
    ) Dummy
where 
  temp_front > first_tempfront and temp_center > first_tempcenter and temp_back > first_tempback
order by rnum
0 голосов
/ 02 мая 2018

Присоединиться к производной таблице, состоящей только из первой строки, и проверить все три столбца в условии WHERE или условии JOIN. Используйте TOP 1, чтобы получить только первую строку, которая удовлетворяет условию.

...