Получить начало и конец процесса в диапазоне дат и времени - PullRequest
2 голосов
/ 03 августа 2020

MySQL запрос, чтобы найти начало и конец процесса в заданном диапазоне дат. В заданном диапазоне дат может быть несколько процессов. Написанный мной запрос дает правильное начало и конец, если есть только один процесс. Если есть 2 процесса, это дает отметку даты и времени начала 1-го процесса и отметку даты и времени окончания второго процесса. Как я могу получить отметку времени начала и окончания обоих процессов (1-го процесса и 2-го процесса)?

Таблица содержит два столбца

  1. date_time, datetime
  2. значение, бит
Table 1 sample data
date_time                   value
2020-02-19 00:10:00           0
2020-02-19 00:11:00           0
2020-02-19 00:12:00           1
2020-02-19 00:13:00           1
2020-02-19 00:14:00           1
2020-02-19 00:15:00           0
2020-02-19 00:16:00           0
2020-02-19 00:17:00           1
2020-02-19 00:18:00           1
2020-02-19 00:19:00           1
2020-02-19 00:20:00           0

Sample output
Rowno     date_time                   value
  3.     2020-02-19 00:12:00            1
  6.     2020-02-19 00:15:00            0

  8.     2020-02-19 00:17:00            1
 11.     2020-02-19 00:20:00            0

Примечание. Когда процесс начинается, значение равно 1, иначе оно равно 0. Чтобы определить время начала, мы должны получить первую строку со значением 1 и предыдущим значением 0. Аналогично для время окончания, мы должны идентифицировать последнюю строку со значением 1 и следующую строку со значением 0.

Запрос: - Определить 1-ю строку со значением 1

    SET @row_number = 0, @result = 0;
    select @result := (a.num - 1) as prev_rec, a.num, a.date_time, a.value from (
        SELECT (@row_number:=@row_number + 1) AS num, date_time, value
        FROM table1
        where date_time >= '2020-02-19 00:00:00' and date_time <= '2020-02-25 23:59:00') as a
    where a.value = 1 
    order by a.date_time limit 1;
-- Check if value for previous rec is 0 to identify start time
    SET @row_number = 0;
    select a.num, a.date_time, a.value from (
        SELECT (@row_number:=@row_number + 1) AS num, date_time, value
        FROM table1 
        where date_time >= '2020-02-19 00:00:00' and date_time <= '2020-02-25 23:59:00') as a
    where a.num = @result 
    order by a.date_time limit 1;

Аналогично I ищите отметку времени окончания

-- Identify last row with value 1
    SET @row_number = 0, @result = 0;
    select @result := (a.num + 1) as next_rec, a.num, a.date_time, a.value from (
        SELECT (@row_number:=@row_number + 1) AS num, date_time, value
        FROM table1 
        where date_time >= '2020-02-19 00:00:00' and date_time <= '2020-02-23 23:59:59') as a
    where a.value = 1 
    order by a.date_time desc limit 1;
-- Check if value for next rec is 0 to identify end time
    SET @row_number = 0;
    select a.num, a.date_time, a.value from (
        SELECT (@row_number:=@row_number + 1) AS num, date_time, value
        FROM table1 
        where date_time >= '2020-02-19 00:00:00' and date_time <= '2020-02-23 23:59:59') as a 
    where a.num = @result
    order by a.date_time limit 1;

Могу ли я найти способ найти решение?

Пожалуйста, простите меня, если я упустил что-то важное. Здесь впервые задаю вопрос.

1 Ответ

1 голос
/ 06 августа 2020

Чтобы сделать это в mysql 8 или mariadb 10.2 или выше, вы просто используете функцию окна задержки:

select date_time, value from (
    select date_time, value, lag(value) over (order by date_time) previous_value
    from mysterytable
) mysterytable_with_lag
where value != previous_value
order by date_time

(необязательно добавьте or value and previous_value is null к предложению where, если вы хотите включить самый ранний row, когда его значение равно 1).

Для более ранних версий вы можете эмулировать функцию задержки с помощью переменных:

select date_time, value from (
    select date_time, value, previous_value
    from (select @previous_value := null) initvars
    cross join (
        select date_time, @previous_value previous_value, @previous_value := value value
        from mysterytable
        order by date_time
    ) mysterytable_post_initvars
) mysterytable_with_lag
where value != previous_value
order by date_time
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...