mysql查询统计列中连续正数

标签 mysql count max

我有一个名为“结果”的表,如下所示:

 ID   -A- -B- -C- -D- -E- -F- 
 1   100 -76  34 -45 54  65
 2    34  -43  57 -12 13 -21
 3    104 -76  34 -45 -3  43
 4    100 -76  -4 -45 54  65
 5    34  -43  57 -12 13 -21
 6    104 -76  34 -45 -3  43

显然有更多的数据,但我认为这足以理解这个想法。

我想要得到的是每列中连续正数的最大计数。

mysql 查询是什么?

感谢您阅读本文。

最佳答案

这是这个想法。对于列中的每个数字,添加一个标志以确定它是否是序列的开头(可以是负数后面的任何数字)。对该值进行累加求和以获得“序列计数”。然后,获取该值的最大值。我将显示一列的代码:

唯一的问题是实现,它需要多个级别的相关子查询。第一个是分配 SequenceStart :

select r.*, rprev.A as prevA, rprev.B as prevB, rprev.C as prevC, rprev.D as prevD,
       (case when (rprev.A < 0 or rprev.A is NULL) then 1 else 0 end) as ASeqStart,
       (case when (rprev.B < 0 or rprev.B is NULL) then 1 else 0 end) as BSeqStart,
       (case when (rprev.C < 0 or rprev.C is NULL) then 1 else 0 end) as CSeqStart,
       (case when (rprev.D < 0 or rprev.D is NULL) then 1 else 0 end) as DSeqStart
from (select r.*,
             (select max(id)
              from results r2
              where r2.id < r.id
             )  previd
      from results r
     ) r left outer join
     results rprev
     on r.previd = rprev.id;

现在,获取累积和很棘手,因为您需要该值两次。不幸的是,MySQL 不允许在 View 中使用子查询。尽管您可以使用下面相同的查询,但让我假设结果已放入表 TempSeq 中。然后执行以下操作为每个值分配一个序列。

select ts.*,
       sum(tsprev.ASeqStart) as ASeqId,
       sum(tsprev.BSeqStart) as BSeqId,
       sum(tsprev.CSeqStart) as CSeqId,
       sum(tsprev.DSeqStart) as DSeqId
from TempSeq ts join
     TempSeq tsprev
     on tsprev.id <= ts.id
group by ts.id;

再一次,让我假设结果存储在另一个临时表中,例如 TempSeqId ,因为您必须多次聚合结果。以下是 A 的示例:

select coalesce(max(seqlen), 0)
from (select ASeqId, count(*) as seqlen
      from TempSeqId
      where a > 0
     ) t

a 的条件可能看起来多余。但存在一个差一的挑战——大多数序列都会以最终的负数结束。对于这些,您只需从计数中减一即可。然而,最终的序列可能不会那样结束,你会低估它。合并适用于所有值为负数的情况。

此时,让我说,如果数据结构存储在具有 id 的行上,那么查询实际上是可行的(甚至作为单个查询)。和sequencename以及一行上的一个值。

编辑:

以上推理是我对这个问题的思考。在 MySQL 中,您可以使用变量以不同的方式解决这个问题。代码更简单:

select MAX(APosCounter) as AMaxLen,
       MAX(BPosCounter) as BMaxLen,
       MAX(CPosCounter) as CMaxLen,
       MAX(DPosCounter) as DMaxLen
from (select r.*,
             @APosCounter := if(A > 0, @APosCounter + 1, 0) as APosCounter,
             @BPosCounter := if(B > 0, @BPosCounter + 1, 0) as BPosCounter,
             @CPosCounter := if(C > 0, @CPosCounter + 1, 0) as CPosCounter,
             @DPosCounter := if(D > 0, @DPosCounter + 1, 0) as DPosCounter
      from results r cross join
           (select @APosCounter := 0, @AMaxLen := 0,
                   @BPosCounter := 0, @BMaxLen := 0,
                   @CPosCounter := 0, @CMaxLen := 0,
                   @DPosCounter := 0, @DMaxLen := 0
            end) const
      order by id
     ) r

这段代码使用变量逻辑来保持每行的“正序长度”的长度。然后它聚合数据以获得最大值。

Here甚至是一个 SQLFiddle 来证明它的工作原理。

关于mysql查询统计列中连续正数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17743520/

相关文章:

mysql - 如何使用 sysdate 功能保存对象

mysql - SQL使用多个查询从同一个表中获取多个值(来自同一列)

mysql - 计算两次之间的分钟数并将其除以记录数

sql - 仅返回该值出现超过 n 次的行

ios - 设置 UITextField 的最大 int 值(不是字符数)

matlab - 如何在 MATLAB 中找到矩阵列中最大值的索引?

mysql - 选择顶部错误

mysql - 计算日期范围内的天数,同时排除重叠天数

c++ - 在 C++ 中使用 min 和 max 函数

mysql - 计数和子选择