Как получить все строки, разделенные на 10 минут, в одном запросе в PHP MySQL? - PullRequest
0 голосов
/ 01 августа 2020

У меня есть таблица устройство , которая содержит записанные значения температуры и время их измерения. Мне нужно выбрать эти данные, извлекая только значения, разнесенные по крайней мере на 10 минут (например, если первая строка читает (30k , 8.40.00), тогда следующая строка содержит значение после или в 8.50.00 (в зависимости от того, какое из следующих значений 10 минут). Мой столбец времени хранится в формате sting (HMS). Мой текущий запрос выбора в PHP равен

$sql="select value ,time from device where time >= '$interval' order by time limit 1";

Используя метод strtotime, значение $ interval увеличивается на 10 минут каждый раз, выбирая только одну строку

Проблема в том, что мне нужно использовать al oop для получения всех возможных строк. Мой вопрос: как получить все строки без использования al oop, как в одном запросе? Для использования for l oop мне нужно заранее знать количество строк.

Ответы [ 3 ]

0 голосов
/ 01 августа 2020

Это сложнее, чем вы думаете. Вы не можете просто просматривать интервалы между последовательными строками, вам нужно отслеживать последнюю выбранную строку, чтобы определить следующую. Это подразумевает итеративный процесс; в SQL это обычно реализуется с помощью рекурсивного запроса, который MySQL поддерживает только начальную версию 8.0.

Учитывайте:

with recursive cte as (
    select value, time 
    from device 
    where time = (select min(time) from device)
    union all
    select d.value, d.time 
    from cte c
    inner join device d on d.time = (
        select min(d1.time) from device d1 where d1.time >= c.time + interval 10 minute
    )
)
select * from cte
0 голосов
/ 01 августа 2020

Я бы посоветовал сначала использовать оконные функции, чтобы получить значение для каждой строки через 10 минут (по крайней мере), а затем применить рекурсивный подзапрос:

with recursive d(value, time, next_time) as (
      select value, time,
             min(time) over (order by time
                             range between interval 10 minute following and unbounded following
                            ) as next_time
      from device
     )
     recursive cte(value, time, next_time) as (
      (select value, time, next_time
       from d 
       order by time
       limit 1
      ) union all
      select d.value, d.time, d.next_time
      from cte join
           d 
           on device.time = cte.next_time
      )
select *
from cte;

Здесь - это скрипт db <>.

0 голосов
/ 01 августа 2020

Думаю, это сработает:

$sql="select `value`,`time` from `device` where MINUTE(`time`) IN (0, 10, 20, 30, 40, 50) order by `time`";

Если у вас есть несколько значений по 10 минут и вы просто хотите одно, используйте группу по МИНУТАМ (time)

...