SQL查询帮助 - 按数字序列分组

时间:2012-10-22 18:57:08

标签: mysql sql

我有一个表,其中包含以下列和数据:

id     dtime        instance     data      dtype

1     2012-10-22     10000       d        1
2     2012-10-22     10000       d        1
..
7     2012-10-22     10004       d        1
..
15    2012-10-22     10000       @        1
16    2012-10-22     10004       d        1
17    2012-10-22     10000       d        1

我想在数据列中对's'的序列进行分组,序列末尾有'@'。

这可以通过实例列进行分组来完成,实例列是一个单独的数据流,但是流中可以有多个序列。

如果在同一个实例中没有数据列,例如,在该实例的最后一个数据之后3秒并且在该间隔内没有找到“@”,我也想结束一个序列。

我已经设法使用游标和while循环来完成这项工作,这对于具有1000行的表来说相当不错,但是这个查询最终会在更多的行上使用,而这两种方法大约需要一分钟数据集只有3-5000行。

在这个网站和其他人看来,似乎基于集合的逻辑可能是要走的路,但是如果没有在每一行上的某种循环将其与其他行进行比较,我认为没办法做我需要的工作。建立'序列'。

如果有人可以提供帮助,或者指出我可能的方向,我们将不胜感激。 :)

理想情况下,我希望以下列格式输出数据:

datacount实例lastdata dtime

20      10000    @      2012-10-22

19      10000    d      2012-10-22

22      10004    @      2012-10-22

20      10022    @      2012-10-22

其中(datacount)是'序列'中行数的计数(这是导致'@'或3秒延迟的数据),(实例)是原始表中的实例ID, (lastdata)是序列中的最后一个数据值,(dtime)是最后一个数据值的日期时间值。

1 个答案:

答案 0 :(得分:1)

让我告诉你如何为最后的'@'做这个。时差遵循类似的想法。关键的想法是在当前行之后获得下一个'@'。为此,您需要一个相关的子查询。之后,您可以通过以下方式进行分组:

select groupid, count(*) as NumInSeq, max(dtime) as LastDateTime
from (select t.*,
             (select min(t2.id) from t t2 where t2.id > t.id and t2.data = '@'
             ) as groupid
      from t
     ) t
group by groupid

处理时间序列有点复杂。它是这样的:

select groupid, count(*) as NumInSeq, max(dtime) as LastDateTime,
       (case when sum(case when data = '@' then 1 else 0 end) > 0 then '@' else 'd' end) as FinalData
from (select t.*,
             (select min(t2.id)
              from t t2
              where t2.id > t.id and
                    (t2.data = '@' or UNIX_TIMESTAMP(t2.dtime) - UNIX_TIMESTAMP(t.dtime) < 3
             ) as groupid
      from t
     ) t
group by groupid