×Закрыть

Статистика по большому количеству полей

Дан объект с 20+ полями числового типа, мапится на одну таблицу.
Хочется считать статистику по каждому полю, там всякие средние, моды, медианы.
Посему 2 вопроса:
1) Есть ли статистические библиотеки для SQL (должно все работать и под MySQL)? Если есть, то ссылки приветствуются.
2) Хотелось бы избежать простыни однотипного кода по генерации запроса переупаковке и тд. (если у вас 20 полей и по всем надо считать, то по крайней мере 20 вызовов будут дублироваться). И при этом без «черной магии» (рефлекшн, макросы и тд.).

LinkedIn
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter
Допустимые теги: blockquote, a, pre, code, ul, ol, li, b, i, del.
Ctrl + Enter

Какого рода статистика нужна?

p.s. Слышал что в хибернейте есть пакет statistics, но он скорее всего для мониторинга/профилирования.

Какого рода статистика нужна?
Статистические функции:
всякие средние, моды, медианы
+ персентили и тд. Каждый столбец в базе — это выборка.
Слышал что в хибернейте есть пакет statistics,
Если вы про org.hibernate.stat — то это совсем про другое.

Возможно не понял вопрос, а чем плохо написать один враппер, который будет по имени таблицы и имени поля и текста условия генерировать запрос и выдавать массив с данными, который можно подставить в функцию. Или тебе нужно одновременно считать по всем 20 полям?

PS
поля одного типа или разных?

Возможно не понял вопрос,
Попробую кодом
class A {
int f1;
int f2;

int f20;
}
Надо получить:
class A {
int avg(f1);
int avg(f2);

int avg(f20);
}
То есть среднее (или какую-то другую статистику по каждому полю). Переупаковать это в json и отправить на клиент. Там уже рисовать по этим данным картинки (по факту бары от fi до fj).
враппер, который будет по имени таблицы и имени поля и текста условия генерировать запрос и выдавать массив с данными, который можно подставить в функцию
Но чтобы заполнить все 20 полей, надо будет руками вызвать этот 20 раз.
поля одного типа или разных?
Наллебл инты.

Если можно считать в серверном коде(MySQL-вскими процедурами будет сложнее), то просто пишешь:
1. генератор кода, который по списку полей, таблице, и условию генерирует запрос в базу.
2. парсер который переведет рекордсет в массив массивов 2D таблицу
3. процедуру в которую передается 2D таблица данных и ссылка на функцию (неважно как реализовать, можно даже через интерфейс), в результате парсер передает в эту функцию каждый столбец и считает данные функции.
4. в результате шага 3 получаем 1D массив уже медиан/среднего или пр
5. пакуем в xml/json

А далее оформляем эту всю приблуду в одну суперфункцию, где на входе, список полей, таблица и условие а на выходе json

Если можно считать в серверном коде
Не хотелось бы.
4. в результате шага 3 получаем 1D массив уже медиан/среднего или пр
5. пакуем в xml/json
И массив метаинформации. А в объект как паковать? Хотелось бы обойтись без черной магии (в своем коде) и руками создавать объект не хочется. Основная мотивация: хочется упростить рефакторинг кода и сохранить поддержку ИДЕ.

так вы бы сами написали, что основная проблема — это создание объекта с произвольным количеством полей.

Хотя функционально, ассоциативный массив не хуже.
php.net/...json-decode.php

Поп поводу расчета на sql сервере — можно использовать динамический SQL

delimiter //
CREATE PROCEDURE dynamic(IN tbl CHAR(64), IN col CHAR(64))
BEGIN
SET @s = CONCAT('SELECT ',col,' FROM ',tbl );
PREPARE stmt FROM @s;
EXECUTE stmt;
END
//
delimiter ;

А далее mysql_fetch_object и получаете объект.

так вы бы сами написали, что основная проблема — это создание объекта с произвольным количеством полей.
Нет. Проблема перепаковать и поддерживать добавление колонок в базу и поля в объект (класс)
Хотя функционально, ассоциативный массив не хуже.
php.net/...json-decode.php
Это к чему? 1) Это не пхп. 2) Хотелось бы получить рефакторинг. 3) Хотелось бы автоматический маппинг при записи в базу.
Нет. Проблема перепаковать и поддерживать добавление колонок в базу и поля в объект (класс)

Тогда вам искать фрейворк-враппер над рефлекшеном.

Тогда вам искать фрейворк-враппер над рефлекшеном.
Спсыбо, Кэп :)
Но чтобы заполнить все 20 полей, надо будет руками вызвать этот 20 раз.
ну все зависит что стоит в where /group by
если там одинаковые условия, то никто не запрещает вызвать один раз
SELECT AVG(f1), AVG(f2) ...
если там одинаковые условия, то никто не запрещает вызвать один раз
SELECT AVG(f1), AVG(f2) ...
А данные на объект как замапить? И что делать когда появится 21-е поле? Править селект, править код который подготавливает данные (по своей сути данные — это мапа).

ну я бы запрос генерил бы, вот мне делать нечего писать двадцать штук AVG руками :)
а количество полей можно наверное как-то конфигом оформить

ну я бы запрос генерил бы, вот мне делать нечего писать двадцать штук AVG руками :)
О и я об этом же :) Вопрос как? Без рефлекшена. И мапить потом их как?

без рефлекшена никак, хотя ... может java сможет, а вас устроит ассоциативный массив имя-значения, аля пшп

а вас устроит ассоциативный массив имя-значения, аля пшп
Да, но если просто использовать мапу, то надо писать маппинг на БД руками + нима поддержки ИДЕ.

ну и если это чет серьезное, я сделал бы промежуточные таблицы в базе, и обновлял бы их по крону или по событию (можно даже на сервере считать), а клиент бы просто обращался к промежуточным таблицам
заодно это бы решило бы проблему пиковых нагрузок, всетаки агрегатные функции недешевы

ну и если это чет серьезное,
В том то и дело что не серьезное. Выборки будут относительно редкие. И хотелось бы как можно меньше писать кода. Хочется максимальной простоты, но все что могу придумать это или работа с сырыми данными (руками запросы, руками сереализация в джсон) или макросы/рефлекшн.

Собственно да, такой себе кеш запросов, процесс на сервере, который проверяет устаревание данных и генерирует новые в зависимости от пула запросов с клиента.

Подписаться на комментарии