Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/74.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
MySQL-重复计算列中两个值之间的行数_Mysql_Sql - Fatal编程技术网

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。让我试试这个解决办法。我会回复你的。