Форум → Разработка → Базы данных → разбиение данных по временным промежуткам
разбиение данных по временным промежуткам
Страницы: ← Следующая страница →
-
Есть табличка:
id int
time datetime
…
уникальные пара (id, time)
Можно ли одним SQL запросом подсчитать кол-во id для нескольких промежутков времени? Например, за последнюю неделю кол-во уникальных id для каждого часа?
Выход:
[table]
[tr][td]count(id)[/td][td]Y-m-d H1-H2[/td][/tr]
[tr][td]34[/td][td]2010-07-09 10-11[/td][/tr]
[tr][td]46[/td][td]2010-07-09 09-10[/td][/tr]
[tr][td]11[/td][td]2010-07-09 08-09[/td][/tr]
[/table]
и т.д.
-
9 июля 2010 г. 12:09, спустя 32 минуты 35 секунд
тебе нужен какой-то "round" для поля ДатаВремя. поройся в докахιιlllιlllι унц-унц -
9 июля 2010 г. 12:17, спустя 7 минут 45 секунд
не обязательно по часам, может быть и 15минутный промежуток) самое главное не знаю как сгенерировать это разбиение -
9 июля 2010 г. 12:25, спустя 8 минут 22 секунды
group by round (unix_timestamp(time) / 900) = 15 минутные промежутки :)Сапожник без сапог -
9 июля 2010 г. 12:55, спустя 30 минут 15 секунд
чет явно не то, не совпадает с кучей отдельных селектов) -
9 июля 2010 г. 13:01, спустя 5 минут 23 секунды
покажи как использовал запрос
чет явно не то, не совпадает с кучей отдельных селектов)Сапожник без сапог -
9 июля 2010 г. 13:08, спустя 7 минут 19 секунд
короче вот такое надо переделать в 1 запрос :)
…
$yesterday = mktime($hour, 0, 0, $month, $day, $year) - 86400;
$interval = 900; // 15 минут
for ($i = 0; $i <= $total; $i += $interval)
{
$cur_e = date("Y-m-d H:i:s", $yesterday - $i);
$cur_b = date("Y-m-d H:i:s", $yesterday - $i - $interval);
$res = mysql_query("SELECT COUNT(DISTINCT login) AS count FROM visits
WHERE visit_begin <= '$cur_e' AND visit_end >= '$cur_b' ");
…
} -
9 июля 2010 г. 13:17, спустя 8 минут 55 секунд
Argnist, говно какое-то.
1. в начале темы ты упоминал одно поле с датой, а тут два. не заморачивайся так - только запутаешь себя.
2. что в данном контексте тебе даёт distinct ???
3. если есть группировка по какому-то полю - должен быть GROUP BY поле. это логически понятно (надеюсь)ιιlllιlllι унц-унц -
9 июля 2010 г. 13:27, спустя 10 минут
1) да не важно 1 дата или нет, главное чтоб попадала в сгенерированные промежутки cur_b - cur_e, остальное я допилю как надо
2) login в таблице не уникальный, Group by по логину не проходит, только с Distinct, тут не надо трогать)Спустя 204 сек.Group by по логину вернет кол-во записей для каждого уникального логина для каждого промежутка времени, а мне надо кол-во уникальных логинов для каждого промежутка времениСпустя 23 сек.поэтому Distinct =) -
9 июля 2010 г. 13:29, спустя 1 минуту 42 секунды
Argnist, если выбираешь кол-во посетителей за последние 15 минут, то логичнее все же сделать как говорить а2д2 - выбрать всех за такой-то промежуток времени, и сгруппировать по имени. Полученный результат посчитать с помощью mysql_num_rows() -
9 июля 2010 г. 13:34, спустя 5 минут 11 секунд
не за последние! а за $total = неделя, месяц год? и тд)) в этом и проблема, все работает, но тыщи отдельных запросов как-то не оч -
9 июля 2010 г. 13:58, спустя 24 минуты
вот чтобы небыло тыщ, делай group by. а чтобы мозг твой не расплавился что именно группировать - группируй по одному полю времени (+ опционально по полю id)
схематично - я использую тип INT для времени - для простоты:
$sql = "SELECT round(({$now}-v.visited)/{$interval}) AS ago, count(*) AS cnt
FROM `visits` AS v
GROUP BY ago";
мне таки кажется, что цель посчитать количество заходов за интервал, а не количество заходов по пользователям, поэтому здесь группировка только по усеченному времениιιlllιlllι унц-унц -
9 июля 2010 г. 14:12, спустя 14 минут 5 секунд
Argnist, тогда алгоритм по типу такого:
1. Выбираем все записи за нужным нам период (берем логин и даты) из базы и кладем в массив. Сортировка по дате должна быть
2. Проходимся по циклу, попутно проверяя на время + уникальность логина в данном диапазоне времени, делаем после каждого "тру" +1 к счетчику.
3. Выводим что нужно куда нужно
Представим что массив уже есть:$array = array();
$array[] = array('time'=>10-10-2010 14:25,'login'=>'Dud');
$array[] = array('time'=>10-10-2010 14:28,'login'=>'Argnist');
$array[] = array('time'=>10-10-2010 14:35,'login'=>'Dud');
$array[] = array('time'=>10-10-2010 14:55,'login'=>'md5');
function get_start_stop($start) {
$interval = 15; // тут ставишь свой временной интервал, только в правильной "валюте". Сам с этим разбирайся
return array('start'=>$start,'stop'=>$start+$interval);
}
$result = array();
$login = array();
foreach ($array as $k=>$v)
{
if ($v['time'] > $youtime['start'] AND $v['time'] <= $youtime['stop'])
{
if (array_key_exists($v['login'],$login) === false)
{
$login[$v['login']] = 1;
}
}
else
{
$result[ $youtime['start'].'-'.$youtime['stop']] = count($login);
$youtime = get_start_stop($youtime['stop']);
$login = array();
}
}
Вот примерно так. Дальше подгоняй под себя сам.Спустя 142 сек.Хотя бля, не, не совсем то. Точнее, направление такое, но я уже понял что это совсем неправильно, ибо пропуски будут. В общем, ну его нах, буду работать лучше. -
-
9 июля 2010 г. 14:18, спустя 1 минуту 42 секунды
phpdude, йопт, не одному тебе флудерастией заниматься.
Да и вообще как-то ведь нужно от работы на пару минут отвлекаться.
Страницы: ← Следующая страница →
Пожалуйста, авторизуйтесь, чтобы написать комментарий!