I apologize in advance - I'm not a DB expert, so there may be a very obvious answer to this that I've missed.
I have a query that counts number of consecutive check-ins by users of a particular status. There are 5 check-in statuses, and we need to count the consecutive check-ins of status 'U' (there are 5 possible statuses: 'U', 'O', 'D', 'F', 'M'). If someone checks in with any other status, the streak stops. After much learning, testing, and failing, I came up with the following query to return the longest streak for any user based primarily on this stackoverflow thread and this stack overflow thread (thanks to authors of those posts/solutions!).
SELECT tmi, static_streak, MAX(count) AS consec
FROM (
SELECT @prev_tmi := @tmi AS prev_tmi,
@prev_s := @status AS prev_s,
@tmi := rtmc.team_member_id AS tmi,
@status := rtmc.status AS status,
@count := if(@prev_s = @status AND @status = 'U', @count + 1, 1) AS count
FROM readiness_team_member_checkins rtmc
CROSS JOIN (SELECT @count:=0) var_init
LEFT JOIN readiness_sessions rs ON rtmc.readiness_sessions_id = rs.readiness_sessions_id
WHERE rtmc.team_member_id = 83
ORDER BY rtmc.readiness_sessions_id, tmi
)
AS sub
GROUP BY tmi
Here are the tables/test data:
CREATE TABLE IF NOT EXISTS `readiness_sessions` (
`readiness_sessions_id` int(11) NOT NULL AUTO_INCREMENT,
`session_date` date NOT NULL,
`session_level` varchar(3) DEFAULT NULL,
PRIMARY KEY (`readiness_sessions_id`,`session_date`)
);
INSERT INTO `readiness_sessions` (`readiness_sessions_id`,
`session_date`,
`session_level`
) VALUES
(1, '2015-09-02', '4'),
(2, '2015-09-03', '4'),
(6, '2015-09-04', '4'),
(7, '2015-09-05', '4'),
(8, '2015-09-06', '4'),
(10, '2015-09-07', '4'),
(11, '2015-09-07', '3'),
(12, '2015-09-08', '4'),
(13, '2015-09-09', '4'),
(14, '2015-09-29', '4'),
(15, '2015-09-30', '4'),
(16, '2015-10-01', '3'),
(17, '2015-10-02', '4'),
(18, '2015-10-06', '4'),
(19, '2015-10-20', '4');
CREATE TABLE IF NOT EXISTS `readiness_team_member_checkins` (
`readiness_team_member_checkins_id` int(11),
`readiness_sessions_id` int(11),
`readiness_team_checkins_id` int(11),
`team_member_id` int(11),
`status` enum('U','D','O','M','F','X')
);
INSERT INTO `readiness_team_member_checkins`
(`readiness_team_member_checkins_id`,
`readiness_sessions_id`,
`team_member_id`,
`status`) VALUES
(1, 1, 83, 'U'),
(2, 2, 83, 'O'),
(3, 6, 83, 'U'),
(4, 7, 83, 'U'),
(5, 8, 83, 'U'),
(6, 10, 83, 'M'),
(7, 11, 83, 'U'),
(8, 12, 83, 'U'),
(9, 13, 83, 'U'),
(10, 14, 83, 'U'),
(11, 15, 83, 'U'),
(12, 16, 83, 'D'),
(13, 17, 83, 'U'),
(14, 18, 83, 'U'),
(15, 19, 83, 'U');
I now have an added feature that requires a second status to be considered in certain circumstances.
The requirement for the new process basically states that a check-in status of 'U' or 'D' will not break the consecutive counting but only 'U' will increment the count - 'D' will be ignored but not break the consecutive counting. I've tried massaging the above query with additional user-defined variables, but I'm rather unfamiliar with this level of mysql.
The included data should return 5 for the current implementation, and would return 8 for the additional requirement.
I have two questions:
The current query usually returns the correct data, but sometimes it will return an incorrect number and I need to reload the query and will get the right number. I hypothesize that this is due to the user-defined variables, which I basically learned to use last week. Any hints on this? I've been unable to reproduce the problem consistently...
Any hints on how I can adapt the above cleanly to get the longest consecutive streak of 'U' not interrupted by 'D' as described in the secondary requirement?
SQL Fiddle here