Я хотел бы сделать что-то вроде следующего:
SELECT AVG([1,2,3]);
Это, конечно, вернет 2. Самое близкое, что у меня есть, это следующее, которое меньше идеала, но может быть поставлено в одну строку:
drop table nums;
create temporary table nums (num int);
insert into nums(num) values(1),(2),(3);
select avg(num) from nums;
Если бы я предположил, что это было бы возможно с другими функциями, такими как variance() и другими.
Редактировать: эта идея из любопытства не является реальной проблемой, которую мне нужно решить.
Я также думаю, что MySQL может быть не лучшим инструментом (поскольку вы не хотели хранить номера), но ответ на ваш вопрос: да, вы можете сделать это с MySQL, не создавая таблицы, если хотите.
Для этого я не нашел встроенных функций/структур, но придумал следующее решение. Моя идея - создать пользовательскую функцию, которая принимает числа в разделительной строке, затем разбивает строку и вычисляет среднее значение чисел. Здесь выполняется реализация, которая работает с целыми числами. Вход должен быть num,num,num
и т.д., Он должен заканчиваться номером (см. Примеры в конце).
DROP FUNCTION IF EXISTS AVGS;
DELIMITER $$
CREATE FUNCTION AVGS(s LONGTEXT) RETURNS DOUBLE
DETERMINISTIC
BEGIN
DECLARE sum BIGINT DEFAULT 0;
DECLARE count BIGINT DEFAULT 0;
DECLARE pos BIGINT DEFAULT 0;
DECLARE lft TEXT DEFAULT '';
-- can we split?
SET pos = LOCATE(',', s);
WHILE 0 < pos DO -- while we can split
SET lft = LEFT(s, pos - 1); -- get the first number
SET s = SUBSTR(s FROM pos + 1); -- store the rest
SET sum = sum + CAST(lft AS SIGNED);
SET count = count + 1;
SET pos = LOCATE(',', s); -- split again
END WHILE;
-- handle last number
SET sum = sum + CAST(s AS SIGNED);
SET count = count + 1;
RETURN sum / count;
END $$
DELIMITER ;
SELECT AVGS("1"); -- prints: 1
SELECT AVGS("1,2"); -- prints: 1.5
SELECT AVGS("1,2,3"); -- prints: 2
Смотрите живую рабочую демонстрацию здесь.
Разница может быть намного сложнее, но я надеюсь, что вы получите эту идею.
Вы используете неправильные инструменты для решения своей проблемы.
Если вы хотите рассчитать дисперсию списка, используйте какой-то язык сценариев, будь то Php, Python и т.д. Если вы хотите сначала сохранить данные и только потом вычислить дисперсию, конечно, используйте что-то вроде MySql.
AVG может иметь только один аргумент. Вам нужно сделать SELECT AVG(num) FROM nums
Вы также можете сделать SELECT SUM(num)/COUNT(num) FROM nums
Просто знайте, поскольку вы делите с помощью ints, что это будет неточно.
select (1+2+3)/3