更多关于MySQL组和聚合的信息,连续几天

时间:2017-04-17 02:22:13

标签: mysql

该表旨在包含宠物及其活动数据,例如睡眠时间和运动时间。表定义如下。

#!/usr/bin/env bash

round() {
  printf "%.${2}f" "${1}"
}

PI=3.14159

round ${PI} 0
echo
round ${PI} 1
echo
round ${PI} 2
echo
round ${PI} 3
echo
round ${PI} 4
echo
round ${PI} 5
echo
round ${PI} 6
echo

# Outputs:
3
3.1
3.14
3.142
3.1416
3.14159
3.141590

# To store in a variable:
ROUND_PI=$(round ${PI} 3)
echo ${ROUND_PI}

# Outputs:
3.142

将以下数据插入表中。

CREATE TABLE IF NOT EXISTS TEST_ACTIVITY(
    pet_id INT(11) UNSIGNED NOT NULL,
    simple_sleep_time INT(11),
    deep_sleep_time INT(11),
    mild_movement_time INT(11),
    moderate_movement_time INT(11),
    severe_movement_time INT(11),
    start_time INT(11) NOT NULL,
    date DATE NOT NULL,
    PRIMARY KEY (pet_id, start_time, date)
) ENGINE=INNODB

运行选择查询后,结果如下:

INSERT INTO TEST_ACTIVITY 
(pet_id, simple_sleep_time, deep_sleep_time, mild_movement_time, moderate_movement_time, severe_movement_time, start_time, date) 
VALUES
(100,  1, 1, 1, 1, 1, 0, '2015-03-10'),
(100,  2, 1, 1, 1, 1, 30, '2015-03-10'),
(100,  3, 1, 1, 1, 1, 60, '2015-03-10'),
(100,  4, 1, 1, 1, 1, 90, '2015-03-10'),
(100,  5, 1, 1, 1, 1, 120, '2015-03-10'),
(100,  6, 1, 1, 1, 1, 150, '2015-03-10'),
(100,  7, 1, 1, 1, 1, 0, '2015-03-11'),
(100,  8, 1, 1, 1, 1, 30, '2015-03-11'),
(100,  9, 1, 1, 1, 1, 60, '2015-03-11'),
(100,  10, 1, 1, 1, 1, 90, '2015-03-11'),
(100,  11, 1, 1, 1, 1, 120, '2015-03-11'),
(100,  12, 1, 1, 1, 1, 150, '2015-03-11'),
(100,  13, 1, 1, 1, 1, 0, '2015-03-12'),
(100,  14, 1, 1, 1, 1, 30, '2015-03-12'),
(100,  15, 1, 1, 1, 1, 60, '2015-03-12'),
(100,  16, 1, 1, 1, 1, 90, '2015-03-12'),
(100,  17, 1, 1, 1, 1, 120, '2015-03-12'),
(100,  18, 1, 1, 1, 1, 150, '2015-03-12'),
(100,  19, 1, 1, 1, 1, 0, '2015-03-13'),
(100,  20, 1, 1, 1, 1, 30, '2015-03-13'),
(100,  21, 1, 1, 1, 1, 60, '2015-03-13'),
(100,  22, 1, 1, 1, 1, 90, '2015-03-13'),
(100,  23, 1, 1, 1, 1, 120, '2015-03-13'),
(100,  24, 1, 1, 1, 1, 150, '2015-03-13'),
(101,  25, 1, 1, 1, 1, 0, '2015-03-10'),
(101,  26, 1, 1, 1, 1, 30, '2015-03-10'),
(101,  27, 1, 1, 1, 1, 60, '2015-03-10'),
(101,  28, 1, 1, 1, 1, 90, '2015-03-10'),
(101,  29, 1, 1, 1, 1, 120, '2015-03-10'),
(101,  30, 1, 1, 1, 1, 150, '2015-03-10'),
(101,  31, 1, 1, 1, 1, 0, '2015-03-11'),
(101,  32, 1, 1, 1, 1, 30, '2015-03-11'),
(101,  33, 1, 1, 1, 1, 60, '2015-03-11'),
(101,  34, 1, 1, 1, 1, 90, '2015-03-11'),
(101,  35, 1, 1, 1, 1, 120, '2015-03-11'),
(101,  36, 1, 1, 1, 1, 150, '2015-03-11'),
(101,  37, 1, 1, 1, 1, 0, '2015-03-12'),
(101,  38, 1, 1, 1, 1, 30, '2015-03-12'),
(101,  39, 1, 1, 1, 1, 60, '2015-03-12'),
(101,  40, 1, 1, 1, 1, 90, '2015-03-12'),
(101,  41, 1, 1, 1, 1, 120, '2015-03-12'),
(101,  42, 1, 1, 1, 1, 150, '2015-03-12'),
(101,  43, 1, 1, 1, 1, 0, '2015-03-13'),
(101,  44, 1, 1, 1, 1, 30, '2015-03-13'),
(101,  45, 1, 1, 1, 1, 60, '2015-03-13'),
(101,  46, 1, 1, 1, 1, 90, '2015-03-13'),
(101,  47, 1, 1, 1, 1, 120, '2015-03-13'),
(101,  48, 1, 1, 1, 1, 150, '2015-03-13'),
(102,  49, 1, 1, 1, 1, 0, '2015-03-10'),
(102,  50, 1, 1, 1, 1, 30, '2015-03-10'),
(102,  51, 1, 1, 1, 1, 60, '2015-03-10'),
(102,  52, 1, 1, 1, 1, 90, '2015-03-10'),
(102,  53, 1, 1, 1, 1, 120, '2015-03-10'),
(102,  54, 1, 1, 1, 1, 150, '2015-03-10'),
(102,  55, 1, 1, 1, 1, 0, '2015-03-11'),
(102, 56, 1, 1, 1, 1, 30, '2015-03-11'),
(102,  57, 1, 1, 1, 1, 60, '2015-03-11'),
(102,  58, 1, 1, 1, 1, 90, '2015-03-11'),
(102,  59, 1, 1, 1, 1, 120, '2015-03-11'),
(102,  60, 1, 1, 1, 1, 150, '2015-03-11'),
(102,  61, 1, 1, 1, 1, 0, '2015-03-12'),
(102,  62, 1, 1, 1, 1, 30, '2015-03-12'),
(102,  63, 1, 1, 1, 1, 60, '2015-03-12'),
(102,  64, 1, 1, 1, 1, 90, '2015-03-12'),
(102,  65, 1, 1, 1, 1, 120, '2015-03-12'),
(102,  66, 1, 1, 1, 1, 150, '2015-03-12'),
(102,  67, 1, 1, 1, 1, 0, '2015-03-13'),
(102,  68, 1, 1, 1, 1, 30, '2015-03-13'),
(102,  69, 1, 1, 1, 1, 60, '2015-03-13'),
(102,  70, 1, 1, 1, 1, 90, '2015-03-13'),
(102,  71, 1, 1, 1, 1, 120, '2015-03-13'),
(102,  72, 1, 1, 1, 1, 150, '2015-03-13');

我想先用这个公式计算每只宠物的每日得分:

select * from TEST_ACTIVITY ORDER BY pet_id, date, start_time;

| pet_id | simple_sleep_time | deep_sleep_time | mild_movement_time | moderate_movement_time | severe_movement_time | start_time | date       |
+--------+-------------------+-----------------+--------------------+------------------------+----------------------+------------+------------+
|    100 |                 1 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-10 |
|    100 |                 2 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-10 |
|    100 |                 3 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-10 |
|    100 |                 4 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-10 |
|    100 |                 5 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-10 |
|    100 |                 6 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-10 |
|    100 |                 7 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-11 |
|    100 |                 8 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-11 |
|    100 |                 9 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-11 |
|    100 |                10 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-11 |
|    100 |                11 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-11 |
|    100 |                12 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-11 |
|    100 |                13 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-12 |
|    100 |                14 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-12 |
|    100 |                15 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-12 |
|    100 |                16 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-12 |
|    100 |                17 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-12 |
|    100 |                18 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-12 |
|    100 |                19 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-13 |
|    100 |                20 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-13 |
|    100 |                21 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-13 |
|    100 |                22 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-13 |
|    100 |                23 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-13 |
|    100 |                24 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-13 |
|    101 |                25 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-10 |
|    101 |                26 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-10 |
|    101 |                27 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-10 |
|    101 |                28 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-10 |
|    101 |                29 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-10 |
|    101 |                30 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-10 |
|    101 |                31 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-11 |
|    101 |                32 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-11 |
|    101 |                33 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-11 |
|    101 |                34 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-11 |
|    101 |                35 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-11 |
|    101 |                36 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-11 |
|    101 |                37 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-12 |
|    101 |                38 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-12 |
|    101 |                39 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-12 |
|    101 |                40 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-12 |
|    101 |                41 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-12 |
|    101 |                42 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-12 |
|    101 |                43 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-13 |
|    101 |                44 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-13 |
|    101 |                45 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-13 |
|    101 |                46 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-13 |
|    101 |                47 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-13 |
|    101 |                48 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-13 |
|    102 |                49 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-10 |
|    102 |                50 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-10 |
|    102 |                51 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-10 |
|    102 |                52 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-10 |
|    102 |                53 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-10 |
|    102 |                54 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-10 |
|    102 |                55 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-11 |
|    102 |                56 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-11 |
|    102 |                57 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-11 |
|    102 |                58 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-11 |
|    102 |                59 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-11 |
|    102 |                60 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-11 |
|    102 |                61 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-12 |
|    102 |                62 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-12 |
|    102 |                63 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-12 |
|    102 |                64 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-12 |
|    102 |                65 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-12 |
|    102 |                66 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-12 |
|    102 |                67 |               1 |                  1 |                      1 |                    1 |          0 | 2015-03-13 |
|    102 |                68 |               1 |                  1 |                      1 |                    1 |         30 | 2015-03-13 |
|    102 |                69 |               1 |                  1 |                      1 |                    1 |         60 | 2015-03-13 |
|    102 |                70 |               1 |                  1 |                      1 |                    1 |         90 | 2015-03-13 |
|    102 |                71 |               1 |                  1 |                      1 |                    1 |        120 | 2015-03-13 |
|    102 |                72 |               1 |                  1 |                      1 |                    1 |        150 | 2015-03-13 |
+--------+-------------------+-----------------+--------------------+------------------------+----------------------+------------+------------+

然后根据其得分确定每只宠物的等级。重要提示:宠物的一日活动数据将在两天内扩大。例如,对于pet_id = 100,2015-03-11的活动数据满足以下条件:

 score = SUM(severe_movement_time) + SUM(moderate_movement_time) + SUM(mild_movement_time) + SUM(simple_sleep_time), 

即2015-03-11的活动数据包含以下6个条目:

(date = DATE_SUB(DATE('2015-03-11'), INTERVAL 1 DAY) AND start_time >= 120 AND start_time <= 150) OR (date = DATE('2015-03-11') AND start_time <= (120 - 30) AND start_time >= 0 ). 

通过使用以下查询,我可以在2015-03-11一天完成。

date=2015-03-10, start_time=120
date=2015-03-10, start_time=150
date=2015-03-11, start_time=0
date=2015-03-11, start_time=30
date=2015-03-11, start_time=60
date=2015-03-11, start_time=90

我的问题是如何编写单个查询来计算连续几天的分数和排名,例如3天(start_date = 2015-03-11,end_date = 2015-03-13)。预期结果如下所列。

SELECT pet_id, date, score, rank
FROM 
(
    SELECT scoreFinder.pet_id, scoreFinder.date, scoreFinder.score, @prev := @curr, @curr := score, @rank := IF(@prev = @curr, @rank, @rank+1) AS rank 
    FROM 
        (
            SELECT pet_id, date, (COALESCE(SUM(severe_movement_time), 0) + COALESCE(SUM(moderate_movement_time), 0) + COALESCE(SUM(mild_movement_time), 0) + COALESCE(SUM(simple_sleep_time), 0)) score 
            FROM TEST_ACTIVITY  
            WHERE ((date = DATE_SUB(DATE('2015-03-11'), INTERVAL 1 DAY) AND start_time >= 120 AND start_time <= 150) OR 
                   (date = DATE('2015-03-11') AND start_time <= (120 - 30) AND start_time >= 0 ))       
            GROUP BY pet_id 
        ) scoreFinder, (SELECT @curr := null, @prev := null, @rank := 0) rank 
    ORDER BY score DESC
) rankFinder

1 个答案:

答案 0 :(得分:1)

这是一个解决方案 - 这里的基本思想是在子查询中生成日期范围,然后将其与TEST_ACTIVITY表连接:

SELECT scores.*,
       @rank := IF(@prev = date, @rank + 1, 1) AS rank,
       @prev := date
FROM   (SELECT pet_id,
               dates.date,
               ( Coalesce(Sum(severe_movement_time), 0)
                 + Coalesce(Sum(moderate_movement_time), 0)
                 + Coalesce(Sum(mild_movement_time), 0)
                 + Coalesce(Sum(simple_sleep_time), 0) ) score
        FROM   (SELECT DISTINCT date
                FROM   TEST_ACTIVITY
                WHERE  date >= '2015-03-11'
                       AND date <= '2015-03-13'
                ORDER  BY date) dates
               JOIN TEST_ACTIVITY t
                 ON ( ( t.date = Date_sub(Date(dates.date), INTERVAL 1 day)
                        AND t.start_time >= 120
                        AND t.start_time <= 150 )
                       OR ( t.date = Date(dates.date)
                            AND t.start_time <= ( 120 - 30 )
                            AND t.start_time >= 0 ) )
        GROUP  BY dates.date,
                  t.pet_id
        ORDER  BY dates.date,
                  score DESC) scores,
       (SELECT @prev := NULL,
               @rank := 0) rank;

测试数据的结果:

pet_id  date    score   rank    @prev := date
102 2015-03-11  351 1   2015-03-11
101 2015-03-11  207 2   2015-03-11
100 2015-03-11  63  3   2015-03-11
102 2015-03-12  387 1   2015-03-12
101 2015-03-12  243 2   2015-03-12
100 2015-03-12  99  3   2015-03-12
102 2015-03-13  423 1   2015-03-13
101 2015-03-13  279 2   2015-03-13
100 2015-03-13  135 3   2015-03-13