Код:
+------+---------------------+------+--------+
| id | time | nick | action |
+------+---------------------+------+--------+
| 1 | 2008-01-02 10:11:23 | user | login |
| 2 | 2008-01-02 11:11:23 | user | logout |
| 3 | 2008-01-02 12:11:23 | user | login |
| 4 | 2008-01-03 11:11:23 | user | logout |
| 5 | 2008-01-04 11:11:23 | user | login |
| 6 | 2008-01-04 12:11:23 | user | login |
| 7 | 2008-01-04 15:11:23 | user | logout |
| 8 | 2008-01-10 16:10:23 | user | login |
| 9 | 2008-01-10 18:10:23 | user | login |
| 10 | 2008-01-10 20:10:23 | user | login |
| 11 | 2008-01-10 23:10:23 | user | logout |
| 12 | 2008-01-11 23:10:23 | user | login |
+------+---------------------+------+--------+
[sql]
select sum(t_end-t_begin) as sec_total, sum(if(t_end>t_begin,1,0)) as cnt from
(select '_' as to_group, UNIX_TIMESTAMP(time) as t_begin,
(select UNIX_TIMESTAMP(`time`) from `log` where nick='user' and id > t1.id order by id limit 1) as t_end
from `log` as t1
where action='login' and nick='user') as t2
group by t2.to_group;
[/sql]
Результат: 126000 sec и 7 периодов. После выборки разделить 126000 на 7 и будет среднее время (но можно поверх обернуть в ещё один select и в нём разделить).
Использовались такие допущения:
1. поле `time` - datetime
2. значения поля `action` - login и logout (только те, между которыми нужно считать время)
3. разница считается между login и первым следующим logout или login, если конечное значение login - оно не учитывается.
-----------------
Фак, не правильно понял, оказывается нужно
получить среднее время входа и выхода в часах человека
а я считаю среднее время пребывания на сайте
-~{}~ 21.01.08 17:13:
Имхо, правильный вариант учитывать вход-выход только между парами login-logout, для случая:
1. login
2. login
3. logout
данные первого login'а будут проигнорированы, так-как точной инфы об окончании сессии нет (можно его учитывать, а время logout'а ставить константой - 5 мин, например):
[sql]
SELECT SEC_TO_TIME(t_in/cnt), SEC_TO_TIME(t_out/cnt) FROM (
SELECT sum(if(t_out is null, 0, t_in)) as t_in, sum(t_out) as t_out, sum(if(t_out is not null,1,0)) as cnt
FROM (
SELECT '_' AS to_group, UNIX_TIMESTAMP(`time`)%86400 AS t_in,
(SELECT if (action='login', null, UNIX_TIMESTAMP( `time` )%86400)
FROM `log`
WHERE nick = 'user' and action in ('login','logout') AND id > t1.id
ORDER BY id
LIMIT 1
) AS t_out
FROM `log` AS t1
WHERE ACTION = 'login' AND nick = 'user'
ORDER BY id
) as t2
GROUP BY t2.to_group
) as t3;
[/sql]