I have a table which records the states of a project:
CREATE TABLE `project_states` (
`id` INT(10) NOT NULL AUTO_INCREMENT,
`state_id` INT(10) NULL DEFAULT NULL,
`project_id` INT(10) NULL DEFAULT NULL,
`created_at` TIMESTAMP NULL DEFAULT NULL,
PRIMARY KEY (`id`)
)
COLLATE='utf8_general_ci'
ENGINE=InnoDB
Some fake data:
id | state_id | project_id | created_at
-----------------------------------------------------
1 | 2 | 8 | 2014-05-27 10:58:12
2 | 3 | 8 | 2014-05-27 11:10:34
3 | 8 | 8 | 2014-05-27 11:56:48
4 | 2 | 10 | 2014-05-27 11:08:34
5 | 4 | 10 | 2014-05-27 11:59:01
I'm trying to get the time difference between two states (say, 2 and 8), and only for the projects which do have both states; in this case, only for project 8 (since 10 doesn't have the state 8).
So far I quite managed to select the projects which match the criteria (have both the values, not just one), but this query returns a tuple of results for each project matched:
SELECT t.*
FROM (
SELECT ps.*
FROM project_states ps
WHERE ps.state_id IN (2,8)
) as t
JOIN project_states pro ON pro.project_id = t.project_id
WHERE pro.state_id = 8
which correctly returns:
id | state_id | project_id | created_at
-----------------------------------------------------
1 | 2 | 8 | 2014-05-27 10:58:12
3 | 8 | 8 | 2014-05-27 11:56:48
I'm quite sure it works since if I add the missing state to the other project, it returns the new tuple of results:
id | state_id | project_id | created_at
-----------------------------------------------------
1 | 2 | 8 | 2014-05-27 10:58:12
3 | 8 | 8 | 2014-05-27 11:56:48
4 | 2 | 10 | 2014-05-27 11:08:34
6 | 8 | 10 | 2014-05-27 12:03:08
But how do I calculate a time difference? I'm using PHP and I know I can loop over the results by project_id and then calculate the difference, but I think there might be a pure SQL solution that would yield me a result like:
project_id | difference
------------------------
8 | 0000-00-00 01:02:00
10 | 0000-00-00 01:05:26
Well, actually my goal would be to calculate the average time difference in which a project lies between these two selected states, so all the records could boil down to just one average value, but that might be a problem I figure out later.
If you have only 2 states you can use simple INNER JOIN. And TIMESTAMPDIFF() to get difference in minutes for example:
SQLFiddle demo
To get average for all projects:
SQLFiddle demo