该表旨在包含宠物及其活动数据,例如睡眠时间和运动时间。表定义如下。
#!/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
答案 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