Методы saveResults и removeResult служат для вставки и удаления данных. Останавливаться на них я не буду, т. к. ничего особенного в них нет. А вот методы getURLData и getGeneralData рассмотрим подробнее. getURLData($urlId) возвращает результаты проверок заданного url. Чтобы не делать два запроса, выборка осуществляется одновременно из обеих таблиц. Из таблицы urls мы получаем адрес, а из results – результаты проверок данного адреса. Чтобы гарантировать отсутствие повторов, в предложении WHERE мы используем условие urls. id=results. urlId. Таким образом, с помощью одного запроса мы получаем все данные необходимые для создания таблицы с результатами проверки выбранного URL. В методе getGeneralData() запрос немного сложнее. Здесь мы должны получить усредненные данные о результатах проверок. Поэтому в запросе для большинства полей используются агрегатные функции. Сразу хочу обратить ваше внимание на выражения вида SUM(results. responsetime)/NULLIF(SUM(results. result), 0). На первый взгляд, кажется, что здесь удобнее использовать функцию AVG, но проблема в том, что у нас могут быть неудачные проверки (когда URL был недоступен). Для них время доступа будет равно 0, т. е. эти результаты не должны учитываться при расчете среднего значения.
Поэтому мы суммируем все значения и делим на количество успешных запросов. Вторая проблема может возникнуть, если успешных запросов не было вообще (деление на ноль). Вообще-то, MySQL в этом случае вернет NULL, что нас устраивает, но другие СУБД могут вернуть ошибку (прервать выполнение запроса). Чтобы этого избежать, мы используем функцию NULLIF. Она принимает два параметра, и возвращает NULL, если они равны. А при делении на NULL ошибок возникать не должно. Предложение FROM urls LEFT JOIN results ON results. urlId=urls. id объединяет таблицу urls с results, причем «левое объединение» гарантирует, что в результат будут включены все адреса из таблицы urls независимо от того, проводились для них проверки или нет. Завершающим этапом мы группируем результаты запроса по полю urls. id (GROUP BY urls. id). Т. е. агрегатные функции будут применяться не ко всем найденным результатам, а отдельно для каждого url. Как видите, этот запрос возвращает все данные, необходимые для создания таблицы на главной странице приложения. С моделями мы закончили, и пора переходить к контроллеру. Но о нем в следующем выпуске . До встречи! P. S. Ссылки на все статьи и примеры цикла я публикую здесь.