Uproszczona struktura Tabela:MySQL GROUP BY i liczyć na wielokrotność WHERE
CREATE TABLE IF NOT EXISTS `hpa` (
`id` bigint(15) NOT NULL auto_increment,
`core` varchar(50) NOT NULL,
`hostname` varchar(50) NOT NULL,
`status` varchar(255) NOT NULL,
`entered_date` int(11) NOT NULL,
`active_date` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `hostname` (`hostname`),
KEY `status` (`status`),
KEY `entered_date` (`entered_date`),
KEY `core` (`core`),
KEY `active_date` (`active_date`)
)
W tym mam następujące zapytanie SQL, które po prostu wynosi obecnie wszystkie rekordy z określonym statusie.
SELECT core,COUNT(hostname) AS hostname_count, MAX(active_date) AS last_active
FROM `hpa`
WHERE
status != 'OK' AND status != 'Repaired'
GROUP BY core
ORDER BY core
Ta kwerenda została uproszczona w celu usunięcia sprzężenia wewnętrzne niepowiązanych danych i dodatkowych kolumn, które nie powinny mieć wpływu na to pytanie.
MAX (data_aktywna) jest taka sama dla wszystkich rekordów danego dnia i zawsze powinien wybrać ostatni dzień lub zezwolić na przesunięcie od TERAZ(). (Jest to pole unixtime)
Chcę zarówno Ilość: (! = Stan status 'OK' i = 'Naprawiony')
I odwrotna ... Ilość: (status = „OK 'OR status = «Naprawiony»)
i pierwsza odpowiedź podzielona przez sekundę, dla «percentage_dead» (Prawdopodobnie tak szybko zrobić w postprocessing)
za ostatni dzień lub offset (- 86400 za wczoraj itd.)
Tabela zawiera około 500 tys. Rekordów i rośnie o około 5000 dziennie, więc pojedyncze zapytanie SQL w przeciwieństwie do zapętlania byłoby naprawdę miłe ..
Wyobrażam sobie, że twórczy IF może to zrobić. Twoja wiedza jest doceniana.
EDYCJA: Jestem otwarty na użycie innego zapytania SQL dla danych bieżących lub danych z offsetu.
EDYCJA: Zapytanie działa, jest wystarczająco szybkie, ale obecnie nie mogę pozwolić użytkownikom sortować kolumny procentowej (tej, która pochodzi ze złych i dobrych wyników). To nie jest korek na pokaz, ale pozwalam im sortować wszystko. ORDER BY tego:
SELECT h1.core, MAX(h1.entered_date) AS last_active,
SUM(CASE WHEN h1.status IN ('OK', 'Repaired') THEN 1 ELSE 0 END) AS good_host_count,
SUM(CASE WHEN h1.status IN ('OK', 'Repaired') THEN 0 ELSE 1 END) AS bad_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 h1.core
ORDER BY (bad_host_count/(bad_host_count + good_host_count)) DESC,h1.core
daje mi: # 1247 - Reference 'bad_host_count' nie są obsługiwane (odniesienie do grupy funkcyjnej)
EDIT: Zrobione dla innej sekcji. Następujące prace i pozwala mi ORDER BY percentage_dead
SELECT c.core, c.last_active,
SUM(CASE WHEN d.dead = 1 THEN 0 ELSE 1 END) AS good_host_count,
SUM(CASE WHEN d.dead = 1 THEN 1 ELSE 0 END) AS bad_host_count,
(SUM(CASE WHEN d.dead = 1 THEN 1 ELSE 0 END) * 100/
((SUM(CASE WHEN d.dead = 1 THEN 0 ELSE 1 END))+(SUM(CASE WHEN d.dead = 1 THEN 1 ELSE 0 END)))) AS percentage_dead
FROM `agent_cores` c
LEFT JOIN `dead_agents` d ON c.core = d.core
WHERE d.active = 1
GROUP BY c.core
ORDER BY percentage_dead
Dziękuję Bill! Nie mogę tego przetestować natychmiast, tak jak skończyłem na cały dzień. Pierwsza część dostaję. Przez chwilę będę musiał zastanowić się nad sekundą. :) –
To właściwie int przechowujący czas epoki, a nie DATETIME. Robić różnicę? –
OK, zmienia sposób obliczania przesunięcia, ale nie ogólnej logiki. Dodam przykład. –