SQL-запрос: как выбирать все следующие строки каждый раз, когда конкретный параметр принимает определенное значение

В моей базе данных есть таблица с 3 столбцами: дата и время, параметр, значение. Моя цель - получить часть данных. Я хочу получить все строки, следующие после параметра = 'B' и значения> 5 (включить эту строку в набор результатов). Оставьте все строки, следующие за параметром = 'B' и значением <=5 (включите эту строку в набор результатов).

Другими словами, я хочу использовать VALUE в строках с параметром = B в качестве флага (псевдокода):

      
    include_flag = 0
    result_set = empty table
    
    for row in rows:
        if parameter = B and value > 5:
            result_set.append(row)
            include_flag = 1
        elif parameter = B and value <= 5:
            result_set.append(row)
            include_flag = 0
        elif parameter <> B:
            if include_flag = 1:
                result_set.append(row)
            elif include_flag = 0:
                skip(row)

исходная таблица:

  • Какое оптимальное решение этой проблемы (ей)?

Любая помощь будет оценена по достоинству.

1 ответ

Вам необходимо иметь уникальный столбец (id) и использовать « OUTER APPLY » для получения ожидаемых результатов.

Поскольку в ваших данных образца нет уникального столбца, я создал временную таблицу, чтобы создать столбец с уникальным идентификатором и сохранить данные образца.

  1. Пример ввода:

  1. создать временную таблицу со столбцом идентификаторов и всеми столбцами из входных данных.
  2. вставьте входные данные в временную таблицу в порядке date_time, чтобы сохранить порядок данных.

Таблица температуры:

  1. напишите свой запрос из этой временной таблицы, чтобы сгенерировать столбец B_over_limit и вставить его в другую временную таблицу для дальнейшего использования.

  1. Теперь напишите запрос с внешним применением, чтобы получить предыдущее значение столбца, когда NULL, чтобы получить окончательный результат.

Запрос:

      select * from tb1 --sample source data
order by date_time

--create temp table #t1 (use original table datatypes)
   create table #t1
   (id int identity not null,
    date_time varchar(50), 
    parameter char(1),
    value float
   )

 insert into #t1  insert input into 
 select * from tb1 order by convert(datetime,date_time)

 select * from #t1;

 SELECT id, t.date_time, t.parameter, t.value, 
   B_over_limit = CASE WHEN t.parameter = 'B' AND t.value > 5.0 THEN 1 
                       WHEN t.parameter = 'B' AND t.value <= 5.0 THEN 0 
                       ELSE null 
                   END 
 into #t2
 FROM #t1 t ORDER BY convert(datetime,t.date_time)

 select * from #t2

 select a.date_time, a.parameter, a.value,
     case when id = 1 and a.B_over_limit is NULL then 0 
     else ISNULL(a.B_over_limit, t.B_over_limit) 
     end as B_over_limit
 from #t2 a
 outer apply
   (select top 1 B_over_limit from #t2 b 
       where b.id < a.id and b.date_time is not null 
         and b.parameter is not null and b.value is not null
         and b.B_over_limit is not null
         and a.B_over_limit is null 
       order by id desc ) t
Другие вопросы по тегам