Этот сайт не наркоманов. Это сайт программистов.

Добро пожаловать на Пыху!

Логин:
Пароль:
 

Нет прописки? Зарегистрируйся!

Новости

Пыха информатор 3.1
Еще более удобное оповещение о флуде!

Краснодарское время: 24 Май, 2012, 10:04:31

Страниц: [1] 2
Печать
Автор Тема: разбиение данных по временным промежуткам  (Прочитано 911 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Argnist    ↓ 
09 Июль, 2010, 11:36:59
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 130
Сила слова: 0

Есть табличка:
id int
time datetime
...
уникальные пара (id, time)
 
Можно ли одним SQL запросом подсчитать кол-во id для нескольких промежутков времени? Например, за последнюю неделю кол-во уникальных id для каждого часа?
Выход:
count(id)Y-m-d H1-H2
342010-07-09 10-11
462010-07-09 09-10
112010-07-09 08-09
и т.д.
  
Записан

artoodetoo    ↓ 
09 Июль, 2010, 12:09:34 , спустя 32 минуты 35 секунд
НЕ ХУЕТА! ХУЕТА!

с особым цинизмом
Группа: в ухо

Карма: 124
Сообщений: 3805
Сила слова: 3.26

тебе нужен какой-то "round" для поля ДатаВремя. поройся в доках
Записан
Argnist    ↓ 
09 Июль, 2010, 12:17:19 , спустя 7 минут 45 секунд
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 130
Сила слова: 0

не обязательно по часам, может быть и 15минутный промежуток) самое главное не знаю как сгенерировать это разбиение
Записан

phpdude    ↓ 
09 Июль, 2010, 12:25:41 , спустя 8 минут 22 секунды
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 344
Сообщений: д-о-х-у-я!
Сила слова: 1.65

group by round (unix_timestamp(time) / 900) = 15 минутные промежутки :)
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Argnist    ↓ 
09 Июль, 2010, 12:55:56 , спустя 30 минут 15 секунд
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 130
Сила слова: 0

чет явно не то, не совпадает с кучей отдельных селектов)
Записан

phpdude    ↓ 
09 Июль, 2010, 01:01:19 , спустя 5 минут 23 секунды
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 344
Сообщений: д-о-х-у-я!
Сила слова: 1.65


чет явно не то, не совпадает с кучей отдельных селектов)
покажи как использовал запрос
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Argnist    ↓ 
09 Июль, 2010, 01:08:38 , спустя 7 минут 19 секунд
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 130
Сила слова: 0

короче вот такое надо переделать в 1 запрос :)
PHP

...
$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' "
);
...
}
Записан

artoodetoo    ↓ 
09 Июль, 2010, 01:17:33 , спустя 8 минут 55 секунд
НЕ ХУЕТА! ХУЕТА!

с особым цинизмом
Группа: в ухо

Карма: 124
Сообщений: 3805
Сила слова: 3.26

Argnist, говно какое-то.
1. в начале темы ты упоминал одно поле с датой, а тут два. не заморачивайся так - только запутаешь себя.
2. что в данном контексте тебе даёт distinct ???
3. если есть группировка по какому-то полю - должен быть GROUP BY поле. это логически понятно (надеюсь)
Записан
Argnist    ↓ 
09 Июль, 2010, 01:27:33 , спустя 10 минут
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 130
Сила слова: 0

1) да не важно 1 дата или нет, главное чтоб попадала в сгенерированные промежутки cur_b - cur_e, остальное я допилю как надо
2) login в таблице не уникальный, Group by по логину не проходит, только с Distinct, тут не надо трогать)
Спустя 3 минуты 24 секунды добавил
Group by по логину вернет кол-во записей для каждого уникального логина для каждого промежутка времени, а мне надо кол-во уникальных логинов для каждого промежутка времени
Спустя 23 секунды добавил
поэтому Distinct =)
Записан

Givi    ↓ 
09 Июль, 2010, 01:29:15 , спустя 1 минуту 42 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 42
Сообщений: 2305
Сила слова: 1.82

Argnist, если выбираешь кол-во посетителей за последние 15 минут, то логичнее все же сделать как говорить а2д2 - выбрать всех за такой-то промежуток времени, и сгруппировать по имени. Полученный результат посчитать с помощью mysql_num_rows()
Записан

Все, что говорят другие - неправда! До тех пор, пока ты сам в это не поверишь.
Если человек дурак, то... чур это не я!
Argnist    ↓ 
09 Июль, 2010, 01:34:26 , спустя 5 минут 11 секунд
НЕ ХУЕТА! ХУЕТА!


Карма: 0
Сообщений: 130
Сила слова: 0

не за последние! а за $total = неделя, месяц год? и тд)) в этом и проблема, все работает, но тыщи отдельных запросов как-то не оч
Записан

artoodetoo    ↓ 
09 Июль, 2010, 01:58:26 , спустя 24 минуты
НЕ ХУЕТА! ХУЕТА!

с особым цинизмом
Группа: в ухо

Карма: 124
Сообщений: 3805
Сила слова: 3.26

вот чтобы небыло тыщ, делай group by. а чтобы мозг твой не расплавился что именно группировать - группируй по одному полю времени (+ опционально по полю id)
схематично - я использую тип INT для времени - для простоты:
PHP

$sql = "SELECT round(({$now}-v.visited)/{$interval}) AS ago, count(*) AS cnt
FROM `visits` AS v
GROUP BY ago"
;
 
мне таки кажется, что цель посчитать количество заходов за интервал, а не количество заходов по пользователям, поэтому здесь группировка только по усеченному времени
Записан
Givi    ↓ 
09 Июль, 2010, 02:12:31 , спустя 14 минут 5 секунд
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 42
Сообщений: 2305
Сила слова: 1.82

Argnist, тогда алгоритм по типу такого:
1. Выбираем все записи за нужным нам период (берем логин и даты) из базы и кладем в массив. Сортировка по дате должна быть
2. Проходимся по циклу, попутно проверяя на время + уникальность логина в данном диапазоне времени, делаем после каждого "тру" +1 к счетчику.
3. Выводим что нужно куда нужно
 
Представим что массив уже есть:
PHP
$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();
    }
}

Вот примерно так. Дальше подгоняй под себя сам.
Спустя 2 минуты 22 секунды добавил
Хотя бля, не, не совсем то. Точнее, направление такое, но я уже понял что это совсем неправильно, ибо пропуски будут. В общем, ну его нах, буду работать лучше.
Записан

Все, что говорят другие - неправда! До тех пор, пока ты сам в это не поверишь.
Если человек дурак, то... чур это не я!
phpdude    ↓ 
09 Июль, 2010, 02:17:10 , спустя 4 минуты 39 секунд
НЕ ХУЕТА! ХУЕТА!

я - ЭМО
Группа: в ухо

Карма: 344
Сообщений: 20789
Сила слова: 1.65

олол, пиздец устроили тут :D
Записан

забанен. могу забанить других, пишите в личку
BEER. Helping ugly people have sex since 1862.
Givi    ↓ 
09 Июль, 2010, 02:18:52 , спустя 1 минуту 42 секунды
НЕ ХУЕТА! ХУЕТА!

Группа: Адекваты

Карма: 42
Сообщений: 2305
Сила слова: 1.82

phpdude, йопт, не одному тебе флудерастией заниматься.
Да и вообще как-то ведь нужно от работы на пару минут отвлекаться.
Записан

Все, что говорят другие - неправда! До тех пор, пока ты сам в это не поверишь.
Если человек дурак, то... чур это не я!
Страниц: [1] 2
Печать
 

Перейти в: