Mysql GROUP BY и СЧЕТ для нескольких операторов Where

Вы рассмотрели использование.RTF как альтернативы?

Это поддерживает изображения встраивания и таблицы, а также текст, открывается значением по умолчанию с помощью Microsoft Word и пока это - featureset, более ограничено (высчитайте любое усовершенствованное форматирование) для чего-то, что стили и открывают как документ Word, это не далеко.

Ваши конечные пользователи, вероятно, не заметят.

5
задан Daren Schwenke 5 November 2009 в 14:37
поделиться

1 ответ

Насколько я понимаю, вы хотите получить количество состояний хостов "ОК" и "Не ОК" на дату последнего действия. Правильно? И затем это должно быть сгруппировано по ядрам.

SELECT core, MAX(active_date)
  SUM(CASE WHEN status IN ('OK', 'Repaired') THEN 1 ELSE 0 END) AS OK_host_count,
  SUM(CASE WHEN status IN ('OK', 'Repaired') THEN 0 ELSE 1 END) AS broken_host_count
FROM `hpa` h1 LEFT OUTER JOIN `hpa` h2 
  ON (h1.hostname = h2.hostname AND h1.active_date < h2.active_date)
WHERE h2.hostname IS NULL
GROUP BY core
ORDER BY core;

Это разновидность проблемы «наибольшее число n на группу», которую я часто вижу в вопросах SQL на StackOverflow.

Сначала нужно выбрать только те строки, которые имеют самую последнюю дату активности для каждого имени хоста, что мы можем сделать, выполнив внешнее соединение для строк с тем же именем хоста и большей active_date. Если мы не находим такого совпадения, у нас уже есть последние строки для каждого заданного имени хоста.

Затем сгруппируйте по ядрам и посчитайте строки по статусу.

Это решение для сегодняшней даты (при условии, что ни одна строка не будет иметь active_date в будущем). Чтобы ограничить результат строками N дней назад, вы должны ограничить обе таблицы.

SELECT core, MAX(active_date)
  SUM(CASE WHEN status IN ('OK', 'Repaired') THEN 1 ELSE 0 END) AS OK_host_count,
  SUM(CASE WHEN status IN ('OK', 'Repaired') THEN 0 ELSE 1 END) AS broken_host_count
FROM `hpa` h1 LEFT OUTER JOIN `hpa` h2 
  ON (h1.hostname = h2.hostname AND h1.active_date < h2.active_date
  AND h2.active_date <= CURDATE() - INTERVAL 1 DAY)
WHERE h1.active_date <= CURDATE() - INTERVAL 1 DAY AND h2.hostname IS NULL
GROUP BY core
ORDER BY core; 

Что касается соотношения между правильными и неработающими именами хостов, я бы рекомендовал просто вычислить это в вашем PHP-коде. SQL не позволяет ссылаться на псевдонимы столбцов в других выражениях списка выбора, поэтому вам придется заключить приведенное выше как подзапрос, а это сложнее, чем в данном случае.


Я забыл, что вы сказали, что вы используя временную метку UNIX. Сделайте что-нибудь вроде этого:

SELECT core, MAX(active_date)
  SUM(CASE WHEN status IN ('OK', 'Repaired') THEN 1 ELSE 0 END) AS OK_host_count,
  SUM(CASE WHEN status IN ('OK', 'Repaired') THEN 0 ELSE 1 END) AS broken_host_count
FROM `hpa` h1 LEFT OUTER JOIN `hpa` h2 
  ON (h1.hostname = h2.hostname AND h1.active_date < h2.active_date
  AND h2.active_date <= UNIX_TIMESTAMP() - 86400)
WHERE h1.active_date <= UNIX_TIMESTAMP() - 86400 AND h2.hostname IS NULL
GROUP BY core
ORDER BY core; 
3
ответ дан 15 December 2019 в 06:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: