mysql 在一张表上进行多个分组

标签 mysql group-by subquery group-concat

我有一张表 job_result

CREATE TABLE job_result  (
  node varchar(20) DEFAULT NULL,
  jobId int(10) DEFAULT NULL,
  subResult int(1) DEFAULT NULL
) 

该表包含许多节点。

每个节点有很多jobId。

每个jobId有很多subResults(通常少于10个)。

提供一些示例数据

insert into job_result values ('A', 14, 0);
insert into job_result values ('A', 15, 0);
insert into job_result values ('A', 16, 1);
insert into job_result values ('A', 17, 0);
insert into job_result values ('A', 18, 1);
insert into job_result values ('A', 19, 1);
insert into job_result values ('A', 20, 0);


insert into job_result values ('B', 1, 0);
insert into job_result values ('B', 2, 0);
insert into job_result values ('B', 3, 1);
insert into job_result values ('B', 4, 1);
insert into job_result values ('B', 5, 1);
insert into job_result values ('B', 6, 1);
insert into job_result values ('B', 7, 1);


insert into job_result values ('C', 10, 0);
insert into job_result values ('C', 11, 0);
insert into job_result values ('C', 12, 0);
insert into job_result values ('C', 13, 0);
insert into job_result values ('C', 14, 0);
insert into job_result values ('C', 15, 0);
insert into job_result values ('C', 16, 0);

我想要一个查询对每个节点进行“健康检查”,以查看节点是否有 X 个连续失败的作业。失败的作业是指至少有一个非零结果的 jobId。

SELECT node, jobId, SUM(subResult) res
FROM job_result WHERE node = 'A' 
GROUP BY jobId 
ORDER BY jobId desc 
LIMIT 5

这为我提供了节点 A 上最后 5 个作业的结果,其中 0 表示作业良好。

+------+---------+------+
| node | jobId   | res  |
+------+---------+------+
| A    |   20    |   0  |
| A    |   19    |   1  |
| A    |   18    |   1  |
| A    |   17    |   0  |
| A    |   16    |   1  |

然后我需要对结果进行求和并将结果分组到每个节点一行中,到目前为止我已经得到了:

SELECT node, SUM(I.res) res
FROM
(SELECT node, sum(subResult) res
FROM job_result WHERE node = 'A' 
GROUP BY jobId 
ORDER BY jobId desc 
LIMIT 5) I

+------+------+
| node | res  |
+------+------+
| A    |  3   |

我的问题是:如何扩展此查询以每个节点返回一行? 我已经尝试了几天相关的子查询和连接,但由于内部选择无法看到要选择的节点,所以我总是失败。 当它到位后,我将努力将 LIMIT 5 更改为动态值。

期望的结果是这样的

+------+------+
| node | res  |
+------+------+
| A    |  3   |
| B    |  0   |
| C    |  1   |
| E    |  0   |

每个节点占一行,右列显示失败次数

请多多指教!

最佳答案

在 MySQL 中,在大型表上,获取最后 5 个结果的最佳方法是使用变量来枚举结果。剩下的只是聚合:

SELECT node, SUM(subr > 0) as numfails
FROM (SELECT node, jobid, subr,
             (@rn := if(@n = node, @rn + 1,
                        if(@n := node, 1, 1)
                       )
             ) as rn
      FROM (SELECT node, jobid,
                   SUM(subresult) as subr
            FROM job_result jr
            GROUP BY node, jobid
           ) jr CROSS JOIN
           (SELECT @n := '', @rn := 0) init
      ORDER BY node, jobid desc
     ) nr
WHERE rn <= 5
GROUP BY node;

关于mysql 在一张表上进行多个分组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30121519/

相关文章:

php - 使用 mysql_free_result($result) 是一个好习惯吗?

MySql 8.0.0 和 Docker 组合问题

php - date_add() 期望参数 1 为 DateTime,给定字符串

postgresql ALL 子查询将空计算为 true

php - symfony2 Doctrine expr 子查询 : Error: Invalid parameter number

php - 将格式化变量存储到 MySQL 数据库中?

sql - 如何计算每月间隔平均值和按月分组

php - SELECT WHERE 组 ID IN 数组 ORDER BY 和 Group By

mysql - 为由多列组成的每个组选择最大版本号

php - MySql Subquery IN 返回第一个结果,而不是所有结果