计算连续的行出现次数

时间:2016-10-30 16:02:02

标签: mysql

我有一个包含三列的MySQL表:takenOn (datetime - primary key)sleepDay (date)type (int)。这张表包含了从睡觉到起床的睡眠数据(每隔一段时间)。

例如,如果我在10月29日晚上11点睡觉并于10月30日早上6点起床,我将有420条记录(7小时* 60分钟)。 takenOn的范围是2016-10-29 23:00:002016-10-30 06:00:00。所有420条记录的sleepDay2016-10-30type是"质量"我的睡眠(1 =睡着,2 =不安,3 =清醒)。我试图得到多少我不安/清醒,这可以通过计算我看到type = 2(或type = 3)连续多少次来计算

到目前为止,我必须遵循查询,该查询仅适用于一天。这是正确的"有效的"这样做的方法(因为这种方法要求我在takenOn)中没有任何"间隙"的数据?另外,如何展开它以计算所有可能的sleepDays

SELECT
    sleepDay,
    SUM(CASE WHEN type = 2 THEN 1 ELSE 0 END) AS TimesRestless,
    SUM(CASE WHEN type = 3 THEN 1 ELSE 0 END) AS TimesAwake
FROM
    (SELECT s1.sleepDay, s1.type
    FROM sleep s1
    LEFT JOIN sleep s2
        ON s2.takenOn = ADDTIME(s1.takenOn, '00:01:00')
    WHERE
        (s2.type <> s1.type OR s2.takenOn IS NULL)
        AND s1.sleepDay = '2016-10-30'
    ORDER BY s1.takenOn) a

我创建了一个SQL小提琴 - http://sqlfiddle.com/#!9/b33b4/3

谢谢!

1 个答案:

答案 0 :(得分:1)

考虑到你所知道的假设,你自己的解决方案非常好。

我在这里提出了一个替代解决方案,它可以很好地处理系列中的差距,并且可以一次使用超过一天。

缺点是它更依赖于非标准的MySql功能(内联使用变量):

select sleepDay,
       sum(type = 2) TimesRestless,
       sum(type = 3) TimesAwake
from (
     select @lagDay as lagDay, 
            @lagType as lagType,
            @lagDay := sleepDay as sleepDay,
            @lagType := type as type
     from   (select * from sleep order by takenOn) s1,
            (select @lagDay := '', 
                    @lagType := '') init
     ) s2
where   lagDay <> sleepDay  
     or lagType <> type
group by sleepDay

要了解它是如何工作的,它可以帮助自己选择第二个select语句。最内层select必须有order by子句,以确保中间查询将按顺序处理记录,这对于那里发生的变量赋值很重要。

查看更新后的SQL fiddle