simplificado la estructura de la tabla:Mysql GROUP BY y contar para múltiples cláusulas 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`)
)
Para ello, tengo la siguiente consulta SQL que simplemente se suma el total de todos los registros con el estado definido.
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
Esta consulta se ha simplificado para eliminar el combinaciones internas de datos no relacionados y columnas adicionales que no debería afectar a la pregunta.
MAX (active_date) es el mismo para todos los registros de un día en particular, y siempre debe seleccionar el día más reciente, o permitir un desplazamiento desde NOW(). (Que es un campo unixtime)
quiero tanto la cuenta de: (! = Estado de estado de 'OK' y = 'reparado')
Y a la inversa ... recuento de: (estado = 'OK 'o estado = 'reparado')
Y la primera respuesta dividido por el segundo, por 'percentage_dead'(probablemente igual de rápido que hacer en el procesamiento posterior)
para bajar el último día o un desplazamiento (- 86400 para ayer, etc.)
La tabla contiene aproximadamente 500k registros y crece por alrededor de 5000 por día, por lo que una única consulta SQL en lugar de bucle sería muy agradable ...
Imagino que algunas IF creativas podrían hacer esto. Tu experiencia es apreciada.
EDITAR: Estoy abierto a utilizar una consulta SQL diferente para los datos de hoy o los datos de un desplazamiento.
EDITAR: La consulta funciona, es lo suficientemente rápida, pero actualmente no puedo dejar que los usuarios ordenen en la columna de porcentaje (la derivada de los recuentos malos y buenos). Esto no es un show stopper, pero les permito clasificar todo lo demás. El ORDER BY de esto:
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
me da: # 1247 - Referencia 'bad_host_count' no es compatible (referencia a la función de grupo)
EDIT: Resuelto por una sección diferente. Las siguientes obras y me permite 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
Gracias Bill! No puedo probar esto inmediatamente aunque ya terminé el día. Primera parte que obtengo Tendré que estudiar el segundo por un tiempo, creo. :) –
En realidad, es un tiempo de almacenamiento int, no DATETIME. ¿Hacer la diferencia? –
Bien, cambia la forma de calcular el desplazamiento, pero no la lógica general. Añadiré un ejemplo. –