简化表结构:
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`)
)
为此,我有以下 SQL 查询,它简单地将所有具有定义状态的记录加起来。
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
此查询已被简化,以删除不相关数据和不应影响问题的额外列的 INNER JOINS。
MAX(active_date) 对于特定日期的所有记录都是相同的,并且应该始终选择最近的一天,或者允许从 NOW() 偏移。(这是一个 UNIXTIME 字段)
我想要两个计数:(状态!='OK'和状态!='修复')
AND 的倒数...计数:(状态 = 'OK' OR status = 'Repaired')
并将第一个答案除以第二个答案,得到“percentage_dead”(在后期处理中可能同样快)
对于最近一天或偏移量( - 昨天的 86400 等。)
表包含大约 500k 条记录,并且每天增长大约 5000 条,因此单个 SQL 查询而不是循环将非常好..
我想一些有创意的 IF 可以做到这一点。您的专业知识值得赞赏。
编辑:我愿意对今天的数据或来自偏移的数据使用不同的 SQL 查询。
编辑:查询工作,足够快,但我目前不能让用户在百分比列上排序(从坏计数和好计数得出的列)。这不是一个表演停止者,但我允许他们对其他所有内容进行排序。这个的顺序:
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
给我:#1247 - 不支持引用“bad_host_count”(引用组函数)
编辑:解决了不同的部分。以下工作并允许我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