выборка с заданной временной точностью

RGmailCom

Новичок
выборка с заданной временной точностью

Здравствуйте.

Есть таблица посещаемости:

id (int, auto_incremetnt) | timemark (int, unix метка в сек) | host (ip адрес) | hits (int, количество кликов в рамках сессии)
Каждая запись - сессия пользователя.


Нужно сделать выборки с часовой, суточной и недельной точностью.

Т.е., к примеру, в случае точности НЕДЕЛЯ получить в результате ряды соот-ие каждой неделе.
Каждый результирующий ряд должен содержать инф. о количестве сессий, сумму уникальных хостов, сумму хитов.


Прошу навести на мысль, или, если сталкивались с подобным указать конкрентную схему запроса.
Как к примеру сделать выборку неделями?

Пока я всю задачу решил опираясь в вычислениях на пхп. Но чувствую что mysql это сможет сделать.

Заранее спасибо за содействие.
 

RGmailCom

Новичок
Гугл думать не умеет а у меня опыта мало. Поэтому решил здесь написать к тому же для форума будет полезно собирать решения еще не освещенных задач. В частности решения подобной задачи не нашел на форуме клуба пхп.


Дата и время вопрос вторичный. Первично же непонятно какими операторами манипулировать:

SELECT sum(hits) as shits,
sum(hosts) as shosts /* как суммировать только уникальные хосты? */,
count(*) /* это количество всех записей, но как суммировать записи текущего промужутка? */
/* способен ли оператор GROUP группировать записи по определенным промежуткам времени ? */
FROM TableA

-~{}~ 13.04.09 05:20:

Вообще несколькими запросами понятно как задачу решить.

Но интересует именно одним запросом. Возможно ли это?
 

Активист

Активист
Команда форума
Про WHERE ты читал что-нибудь?
Что-нибудь типа такого:

[sql]
SELECT COUNT(`id`) FROM `you_date_row` WHERE `you_date_row` BETWEEN '2009-01-01' AND '2009-02-01' GROUP BY `hosts`
[/sql]

[sql]
SELECT SUM(`hits`) AS `hits`, SUM(`hosts`) AS `hosts`FROM `stat` WHERE `you_date_row` BETWEEN '2009-01-01' AND '2009-02-01'
[/sql]

И зачем использовать метку в секундах, когда есть специализированные типы данных DATETIME, DATE, TIME ?
 

RGmailCom

Новичок
Активист

Схема запроса предложенная Вами предполагает его повторение.

Т.е. для каждой новой недели (если я выбираю по неделям) я должен делать отдельный запрос, согласно Вашему примеру.

За такого рода решением я бы не полез тревожить умных людей.

Я интересуюсь схемой запроса, которая выдавала бы каждый период выборки соот-им рядом. При этом каждый ряд содержал бы сумму хитов, хостов и пр. соот-ую данному периоду.

По поводу DATETIME etc - просто привык использовать секундную метку; опять таки это вопроса касается косвенно. Периодом точности может быть и период в полминуты.
 

RGmailCom

Новичок
zerkms

предлагаете, такую схему?

SELECT SUM( `hits` ) AS `hits` , SUM( `hosts` ) AS `hosts`
FROM `stat`
WHERE `you_date_row`
BETWEEN '2009-01-01' AND '2009-02-01'

UNION


SELECT SUM( `hits` ) AS `hits` , SUM( `hosts` ) AS `hosts`
FROM `stat`
WHERE `you_date_row`
BETWEEN '2009-01-01' AND '2009-02-01'

UNION...

(дублируем запрос с разлищающимися периодами и объединяем) ?

насколько это эффективно?..
 

Grezz

Новичок
для группировки по неделям:

GROUP BY DATE_FORMAT(timemark, '%x%v');

Только в твоём случае для timemark еще надо применить FROM_UNIXTIME
 

Активист

Активист
Команда форума
RGmailCom
> Периодом точности может быть и период в полминуты
WHERE `you_datetime_row` > "2009-01-02 10:20:30" ? (например?)

Судя по количеству запросов, применение FROM_UNIXTIME вызовет избыточную нагрузку. Используйте тип DATETIME.

В указанных мой примерах - направление движения. Что, куда и как вытаскивать из БД зависит от конкретных задач. Результаты выборки всегда можно сгруппировать (н-р по примеру Grezz), объеденить. Где-то можно обойтись простым запросом, где-то составным, где-то использовать объединение (JOIN).

Не надо зацикливаться на "выполнить только один запрос". Можно и несколько.

И наверняка, хороший SQL заменить большой блок Вашего кода.
 

RGmailCom

Новичок
Большое спасибо! Вопрос решен благодаря вам.

GROUP BY DATE_FORMAT(timemark, '%x%v');
GROUP BY DATE_FORMAT(timemark, '%x%c');
GROUP BY DATE_FORMAT(timemark, '%k');

etc

решает вопросы как надо!

Спасибо ещё раз!

-~{}~ 13.04.09 18:57:

Ещё вопрос в рамках этой темы. Последний. Тоже прошу указать куда копать (гуглил, читал ман - видать плохо)

В итоге я имею результат от базы сгруппированный по временным интервалам: каждый ряд результата - интервал.

Как я могу узнать потенциально возможное количество рядов?

Конечно если один ряд - одна запись - понятно как -- count(*)

Но тут один ряд - результат группировки неопределенного количества рядов. Собственно поэтому и вопрос.
 

RGmailCom

Новичок
*****,

SELECT count(*) GROUP BY временной_интервал

будет выдавать количество записей в каждой группе
но не количество рядов в результате.
 

Фанат

oncle terrible
Команда форума
количетсво рядов в результате выдает функция mysql_num_rows
 

RGmailCom

Новичок
*****

спасибо за внимание.

но я интересуюсь о потенциально возможных количествах рядов.

неочень правильно делать глобальный SELECT который может затронуть миллион(ы) рядов, чтобы таким образом узнать общее количество рядов.

очевидно необходимое для листинга.
 

Grezz

Новичок
(дата_максимальная - дата_минимальная) / продолжительность_периода
и вся вот эта красота округляетсяв большую сторону

тогда получаешь максимально возможное количество периодов фиксированной длительности за указанный промежуток времени.
 

Gorynych

Посетитель PHP-Клуба
если речь о задаче "популярность / рейтинг / просмотров за сегодня / неделю / месяц / все время" то, в случае успеха проекта, попытка держать все скопом и считать на лету вас убьет
 

RGmailCom

Новичок
Gorynych

В то же время оптимизация SQL запросов одна из важнейших составляющих глобальной задачи оптимизации вычислений.
 
Сверху