MySQL-重复计算列中两个值之间的行数
我有一张这样的桌子MySQL-重复计算列中两个值之间的行数,mysql,sql,Mysql,Sql,我有一张这样的桌子 id | status | data | date ----|---------|--------|------- 1 | START | a4c | Jan 1 2 | WORKING | 2w3 | Dec 29 3 | WORKING | 2d3 | Dec 29 4 | WORKING | 3ew | Dec 26 5 | WORKING | 5r5 | Dec 23 6 | START | 2q
id | status | data | date
----|---------|--------|-------
1 | START | a4c | Jan 1
2 | WORKING | 2w3 | Dec 29
3 | WORKING | 2d3 | Dec 29
4 | WORKING | 3ew | Dec 26
5 | WORKING | 5r5 | Dec 23
6 | START | 2q3 | Dec 22
7 | WORKING | 32w | Dec 20
8 | WORKING | 9k5 | Dec 10
and so on...
我想做的是得到两个“开始”之间的“工作”行数,即
id | status | count | date
----|---------|--------|-------
1 | START | 4 | Jan 1
6 | START | 2 | Dec 22
and so on ...
我使用的是MySql 5.7.28
非常感谢任何帮助/建议 date在示例中不可用,请尝试使用id作为排序列
select id, status,
(select count(*)
from mytable t2
where t2.id > t.id and t2.status='WORKING'
and not exists (select 1
from mytable t3
where t3.id > t.id and t3.id < t2.id and status='START')
) count,
date
from mytable t
where status='START';
假设id是安全的,则可以通过查找每个块的下一个id并分配一些伪值,然后按下一个id分组来实现
drop table if exists t;
create table t
(id int,status varchar(20), data varchar(3),date varchar(10));
insert into t values
( 1 , 'START' , 'a4c' , 'Jan 1'),
( 2 , 'WORKING' , '2w3' , 'Dec 29'),
( 3 , 'WORKING' , '2d3' , 'Dec 29'),
( 4 , 'WORKING' , '3ew' , 'Dec 26'),
( 5 , 'WORKING' , '5r5' , 'Dec 23'),
( 6 , 'START' , '2q3' , 'Dec 22'),
( 7 , 'WORKING' , '32w' , 'Dec 20'),
( 8 , 'WORKING' , '9k5' , 'Dec 10');
SELECT MIN(ID) ID,
'START' STATUS,
SUM(CASE WHEN STATUS <> 'START' THEN 1 ELSE 0 END) AS OBS,
Max(DATE) DATE
FROM
(
select t.*,
CASE WHEN STATUS = 'START' THEN DATE ELSE '' END AS DT,
COALESCE(
(select t1.id from t t1 where t1.STATUS = 'START' and t1.id > t.id ORDER BY T1.ID limit 1)
,99999) NEXTID
from t
) S
GROUP BY NEXTID;
+------+--------+------+--------+
| ID | STATUS | OBS | DATE |
+------+--------+------+--------+
| 1 | START | 4 | Jan 1 |
| 6 | START | 2 | Dec 22 |
+------+--------+------+--------+
2 rows in set (0.00 sec)
选择id、状态、计数、日期`
从中选择@count`count`,
身份证件
地位
`日期`,
@计数:=@status=status*@count+1,
@状态:=状态
从测试来看,
选择@count:=0,@status:=init\u vars
按id描述订购
计算
状态为“开始”的位置
按id订购
>既然我还在设计/开发阶段,我可以转移到MySQL 8,如果这能让这个逻辑变得更容易的话?你知道如何使用Windows功能实现这一点吗N0000B
以cte作为选择id,
地位
`日期`,
SUMstatus='WORKING'按id描述加工
从测试
按id订购
选择id,
地位
加工-按id,0`count`,在订单上合并LeadWorkings,
`日期`
来自cte
状态为“开始”的位置
按id订购
这是一种间隙和孤岛问题,在MySQL 8+中使用窗口函数更简单 在较旧的版本中,可能最有效的方法是累积开始数,以定义行的分组。您可以使用变量执行此操作,然后聚合:
select min(id) as id, 'START' as status, sum(status = 'WORKING') as num_working, max(date) as date
from (select t.*, (@s := @s + (t.status = 'START')) as grp
from (select t.* from t order by id asc) t cross join
(select @s := 0) params
) t
group by grp
order by min(id);
是一个数据小提琴。你真的有这种格式的日期吗?它们是正确的日期吗?获取任务在某些排序用法中需要的两个“开始”之间的“工作”行数。按id排序是否安全?第6行和第7行之间是哪两个开始?@P.Salmon感谢您的回复。目前,我只使用day格式存储日期,但我可以添加一列或更改当前日期列,以Unix时间戳或MySQL时间戳格式存储日期。@Akina:谢谢您的回复。id是表的自动递增主键,所以我认为它是唯一的并且递增的。这可以简化吗?@草莓我不明白你的问题。你想简化什么?这是绝对简单和明确的现在-如果有人不能理解,那么他可能只执行子查询计算,并调查其结果。谢谢秋叶,我会尝试你的解决方案,并返回给你。谢谢你的答复。我将数据存储为仅限白天的格式,以便更轻松地分组。但是,如果这样做可以简化每次开始计算行数的逻辑,那么我也可以将日期存储在时间戳中。谢谢您的回复。我试试看。既然我还在设计/开发阶段,我可以转移到MySQL 8,如果这能让这个逻辑变得更容易的话?你知道如何使用Windows功能实现这一点吗?@N0000B。这个问题显然是关于MySQL 8+之前的版本。请再问一个问题以获得8+的解决方案。谢谢,P。让我试试这个解决办法。我会回复你的。