structure simplifiée Tableau:Mysql GROUP BY et COUNT pour plusieurs clauses 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`)
)
Pour cela, je la requête SQL suivante qui totalise simplement tous les enregistrements avec le statut défini.
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
Cette requête a été simplifiée pour supprimer le INNER REJOINT à des données non liées et des colonnes supplémentaires qui ne devraient pas avoir une incidence sur la question. MAX (active_date) est le même pour tous les enregistrements d'un jour particulier, et doit toujours sélectionner le jour le plus récent ou autoriser un décalage de NOW() à 0 (0). (C'est un champ unixtime)
Je veux à la fois le nombre de: (! Status = 'OK' et status = 'Réparé')
et l'inverse ... le nombre de: (status = « OK OR status = « réparé »)
et la première réponse divisée par la seconde, pour « percentage_dead » (probablement tout aussi rapide à faire en post-traitement)
pour le dernier jour ou un décalage (- 86400 pour hier, etc ..)
Table contient environ 500k enregistrements et se développe par environ 5 000 par jour, donc une seule requête SQL par opposition à la boucle serait vraiment bien ..
J'imagine que certains IF créatifs pourraient le faire. Votre expertise est appréciée.
EDIT: Je suis ouvert à l'utilisation d'une requête SQL différente pour les données d'aujourd'hui ou les données d'un décalage.
EDIT: La requête fonctionne, elle est assez rapide, mais je ne peux actuellement pas laisser les utilisateurs trier sur la colonne de pourcentage (celle dérivée de mauvais et bons comptes). Ce n'est pas un bouchon de spectacle, mais je leur permet de trier tout le reste. ORDER BY de ceci:
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
Ça me donne: # 1247 - Référence 'bad_host_count' non pris en charge (référence à la fonction de groupe)
EDIT: Résolu pour une autre section. Les travaux suivants et me permet de 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
Merci Bill! Je ne peux pas tester cela immédiatement mais comme je l'ai fait pour la journée. Première partie que je reçois. Je vais devoir étudier la seconde pendant un moment je pense. :) –
Il s'agit en fait d'une époque de stockage int, pas DATETIME. Faites une différence? –
Ok, ça change comment vous calculez le décalage, mais pas la logique générale. Je vais ajouter un exemple. –