У меня есть база данных, содержащая таблицу объектов (сетевых устройств) и таблицу событий, содержащую отметки времени, когда они не могут быть достигнуты с помощью ping. Таблица не содержит никакой информации о том, когда они МОГУТ пинговаться, только когда они были недоступны.
Чтобы вычислить «время простоя», я создал php-скрипт, который получает любые чётные значения в течение n секунд от предыдущей строки события для этого объекта. Сценарий в итоге состоит из ~ 50-100 отдельных запросов, и я не уверен, как вписать это в один запрос SQL.
Любая помощь приветствуется!
function GetDownTime(PDO $sql, $Objid) {
$DownChain=array();
$Last=null;
$i=1;
while($Last!==False) {
try {
// Select the down timestamp for the correct object
// where down is LESS THAN the last down pulled (or current time if this is the first attempt)
// where down is not greater than or equal to expired
// expired is the last timestamp minus 600 (10 minutes). - this means we wont grab timestamps after a 10 minute gap (uptime)
$GetEvent=$sql->Prepare("SELECT down,UNIX_TIMESTAMP(down) as unix FROM events
WHERE obj_id=:objid
AND UNIX_TIMESTAMP(down) < :last
AND UNIX_TIMESTAMP(down) >= :expired
ORDER BY down DESC
LIMIT 1");
$GetEvent->Execute(array(
':objid' => $Objid
,':last' => ($Last ? $Last : time())
,':expired' => $Last-(DOWNTIME_MAXHOPSIZE ? DOWNTIME_MAXHOPSIZE : 600) // If for any reason the function can't get the constant value then default to 600
));
} catch (PDOException $e) {
die($e->getmessage());
}
if($GetEvent->RowCount()==1) {
// Event found
$Event=$GetEvent->Fetch(PDO::FETCH_ASSOC);
$Last = $Event['unix'];
$DownChain[] = $Event['unix'];
} else {
// Event not found
$Last=false;
}
$i++;
}
/* etc etc */
}
Это согласуется с подходом, отмеченным @JohnMcMahon в комментариях. Не ограничивайте набор результатов, просто извлекайте по одной строке за раз (т.е. выполняйте итерации строк БД) и не позволяйте циклу считывать записи, как только вы найдете запись, которая нарушает ваше условие. Здесь нет необходимости в сложном запросе.
Других решений пока нет …