原文:Counting non-contiguous values
我会稍微改变一下这个结构,这样我就可以做的更明显了。
鉴于:
+------+---------------+---------------+----+
| guid | current_level | current_value | pk |
+------+---------------+---------------+----+
| a | 100 | 12 | 1 |
| a | 200 | 12 | 2 |
| a | 200 | 12 | 3 |
| a | 200 | 12 | 4 |
| a | 300 | 14 | 7 |
| a | 300 | 12 | 9 |
| a | 200 | 14 | 12 |
| b | 100 | 10 | 5 |
| b | 100 | 10 | 8 |
| b | 200 | 12 | 11 |
| b | 100 | 12 | 13 |
| b | 200 | 12 | 14 |
| b | 300 | 12 | 15 |
| b | 200 | 12 | 16 |
+------+---------------+---------------+----+
我想计算每个guid
进入200级的总次数,忽略它保持在200的行。所以200级的连续行应该被视为1,而从200的转换 - > 100(或300) - > 200将计为2。
鉴于上述结构,我正在寻找的结果是:
+------+-------+-------+
| guid | level | times |
+------+-------+-------+
| a | 200 | 2 |
| b | 200 | 3 |
+------+-------+-------+
原始问题(上面链接的)在技术上确实有效,但是当在具有1.8M行的表上使用该解决方案时,它需要大约30秒,这不是最佳的。
注意:解决方案(sq)的内部子查询往往花费不到一秒钟,但整个查询表现不佳(如果有人可以解释为什么会这样,我会很感激,可能是因为它的大尺寸临时表?)
问题是在给定表格大小的情况下完成我正在尝试的内容的有效方法。
旧查询参考:
SELECT guid, SUM(TIMES) FROM (
SELECT guid, current_level ,
if(@id <> guid, @lev := 10, 0) AS useless,
if(@id <> guid, @id := guid, 0) AS useless2,
(case when (current_level = 200
AND current_level <> @lev) then 1 else 0 end) as TIMES,
if(current_level <> @lev, @lev := current_level, 0) AS useless3
FROM sensor_logs
, (SELECT @id := 'none', @lev := 10) var_init_subquery
ORDER BY guid
) sq
GROUP BY guid
答案 0 :(得分:1)
您已经提到性能是您关注的问题,尝试任何类型的选择查询同样需要时间,因为记录数量会增加。
在我看来,方法是
我觉得总体而言,这将优化性能
答案 1 :(得分:0)
大多数情况下,由于语法错误和未经测试,在MySQL中使用会话变量时会出错。在下面的查询中,我们使用两个会话变量。第一个guid_no
存储当前级别值的滞后。 guid_no
变量存储了200
的延迟。然后,计算匹配行的逻辑是,我们遇到非200
值的guid_no
值, guid_no
未更改。然后,SET @current_level = NULL;
SET @guid_no = NULL;
SELECT
t.guid,
SUM(guid_sum) AS times
FROM
(
SELECT
CASE WHEN (@current_level <> 200 AND current_level = 200) AND (@guid_no = guid)
THEN 1 END AS guid_sum,
@current_level:=current_level,
@guid_no:=guid AS guid,
current_value,
pk
FROM sensor_logs
ORDER BY guid, pk
) t
GROUP BY t.guid;
可以通过聚合来获得您想要的最终结果。
save_path='/home/imagefolder'
for i in range(1,11):
name=i
fullname=os.path.join(save_path,str(name)+".png")
<强>输出:强>
在这里演示:
顺便说一句,如果您在MySQL中使用会话变量来模拟行号功能,那么这是一个很好的参考,我觉得非常有帮助: