我有一个名为“结果”的表,如下所示:
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查询?
感谢您阅读本文。
答案 0 :(得分:0)
select GREATEST(
sum(if (A <= 0, 0,1)),
sum(if (B <= 0, 0,1)),
sum(if (C <= 0, 0,1)),
sum(if (D <= 0, 0,1)),
sum(if (E <= 0, 0,1)),
sum(if( F <= 0, 0,1))
) FROM RESULT
答案 1 :(得分:0)
这是个主意。对于列中的每个数字,添加一个标志以确定它是否是序列的开头(将是负数后面的任何内容)。执行此值的累积和以获得“序列计数”。然后,获取此值的最大值。我将展示一列的代码:
唯一的问题是实现,它需要多级相关子查询。第一个是分配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不允许视图中的子查询。虽然您可以使用下面的相同查询,但我假设结果放在表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。