в таблице юзеров есть столбик "день рождения".
записи в нем выглядят таким образом: гггг-мм-дд.
на данный момент в таблице более полутора миллиона юзеров и продолжает стремительно рости.
подскажите пожалуйста как мне лучше всего найти средний возраст юзеров.
проверка будет происходить раз в 5-10 минут так что надо максимально эффективно ибо таблица очень большая.
вытащить все как есть а потом на пхп конвертировать и подсчитывая средний возраст мне кажется очень ресурсоемким.
думал написать запрос с AVG но как внутри запроса конвертировать такой вид даты в то что поймет SQL?
короче подскажите, эксперты.
всем заранее спасибо!
Спустя 7 минут, 16 секунд (26.06.2012 - 09:53) Nikitian написал(а):
Добавить табличку или поле, куда каждый день пересчитывать возраст и считать статистику по нему.
Спустя 3 минуты, 4 секунды (26.06.2012 - 09:56) MatrixGod написал(а):
Nikitian, не могу. у меня доступ к базе только для чтения.
я систему мониторинга делаю. один из мониторов должен показывать средний возраст.
база данных как бы не моя. поэтому только для чтения...
я систему мониторинга делаю. один из мониторов должен показывать средний возраст.
база данных как бы не моя. поэтому только для чтения...
Спустя 56 минут, 52 секунды (26.06.2012 - 10:53) walerus написал(а):
MatrixGod Я так думаю, что кроме как делать выборку из базы, а потом высчитывать среднее значение, других вариантов нет, т.к. если искать минимальное и максимальное значение года, то все равно прийдется делать выборку, для удаления лишних символов кроме года.
p.s. В базах не "Гуру" ), по этому мб как то иначе можно сделать ).
p.s. В базах не "Гуру" ), по этому мб как то иначе можно сделать ).
Спустя 25 минут, 42 секунды (26.06.2012 - 11:19) killer8080 написал(а):
как вариант можно попробовать так. На счет производительности на 1 млн записей не знаю, проверяй. Есть один недостаток, в расчетах учитывается только год и месяц, будет не большая погрешность
SELECT
AVG(
FLOOR(
period_diff(
EXTRACT(YEAR_MONTH FROM NOW() ) ,
EXTRACT( YEAR_MONTH FROM `date` )
) / 12
)
)
FROM `table`
Спустя 12 минут, 43 секунды (26.06.2012 - 11:31) sergeiss написал(а):
А как это "нет полноценного доступа к БД"???
При его отсутствии предлагают так сделать. В предположении, что ты хотя бы файлы писать-читать можешь
Итак. Исходные данные:
- доступа к БД на запись нету, есть только чтение
- в нужной таблице есть некий уникальный, автоинкрементный айди
- определим возраст юзеров от 5 до 100 лет. Вряд ли кто-то будет выбиваться из этого диапазона
1. Пишем файл, в котором 97 строк: первая строка - последний АйДи, который мы использовали в БД, а затем 96 строк формата "возраст: количество".
2. Читаем файл: на выходе переменная и массив. Зная последний юзаный айди, можем найти только новые строки. Читаем из БД только их.
3. Обрабатываем данные, добавляем данные о возрасте к нужному элементу массива.
4. По окончании обработки сохраняем данные в файле с тем же именем и в том же формате, но с новыми данными. Либо - сериализуем массив перед записью, чтобы потом кода писать на чтение и на запись.
5. Через 5-10 минут повторяем процедуру. И нефиг дёргать всё записи в таблице!!! Работаем только с новыми данными!
PS. Реальный код написать быстрее было бы, чем этот текст
При его отсутствии предлагают так сделать. В предположении, что ты хотя бы файлы писать-читать можешь

Итак. Исходные данные:
- доступа к БД на запись нету, есть только чтение
- в нужной таблице есть некий уникальный, автоинкрементный айди
- определим возраст юзеров от 5 до 100 лет. Вряд ли кто-то будет выбиваться из этого диапазона
1. Пишем файл, в котором 97 строк: первая строка - последний АйДи, который мы использовали в БД, а затем 96 строк формата "возраст: количество".
2. Читаем файл: на выходе переменная и массив. Зная последний юзаный айди, можем найти только новые строки. Читаем из БД только их.
3. Обрабатываем данные, добавляем данные о возрасте к нужному элементу массива.
4. По окончании обработки сохраняем данные в файле с тем же именем и в том же формате, но с новыми данными. Либо - сериализуем массив перед записью, чтобы потом кода писать на чтение и на запись.
5. Через 5-10 минут повторяем процедуру. И нефиг дёргать всё записи в таблице!!! Работаем только с новыми данными!
PS. Реальный код написать быстрее было бы, чем этот текст

Спустя 22 минуты, 21 секунда (26.06.2012 - 11:54) Placido написал(а):
Еще вариант
Проверял производительность на таблице в 2 млн записей - 1,2 сек. Вариант killer8080 - 2,3 сек.
SELECT FLOOR(AVG(DATEDIFF(CURDATE(), `день рождения`))/365.25) AS `средний возраст` FROM `таблица`;
Проверял производительность на таблице в 2 млн записей - 1,2 сек. Вариант killer8080 - 2,3 сек.
Спустя 4 часа, 50 минут, 48 секунд (26.06.2012 - 16:44) MatrixGod написал(а):
killer8080
Placido
мне никогда раньше не приходилось писать запросы в которых каким-то образом приходится манипулировать датами. это то что я искал, помоему. спасибо!
sergeiss
и тебе спасибо, твоя идея тоже хорошая, файлы я конечно создавать могу.
остается выбрать один из ваших вариантов.
Placido
мне никогда раньше не приходилось писать запросы в которых каким-то образом приходится манипулировать датами. это то что я искал, помоему. спасибо!
sergeiss
и тебе спасибо, твоя идея тоже хорошая, файлы я конечно создавать могу.
остается выбрать один из ваших вариантов.

Спустя 2 часа, 38 минут, 7 секунд (26.06.2012 - 19:23) sergeiss написал(а):
Цитата (MatrixGod @ 26.06.2012 - 17:44) |
остается выбрать один из ваших вариантов. |
Сначала лучше попробовать оба варианта. А выбор получится в итоге сам собой, на основе более быстрого и надежного варианта.