我想做以下事情:
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;
如果有一种方法,我认为使用variant()和其他函数也可以实现这一点。
编辑:这种想法出于好奇,不是我需要解决的真正问题。
答案 0 :(得分:0)
AVG只能有1个参数。您需要做SELECT AVG(num) FROM nums
您也可以执行SELECT SUM(num) / COUNT(num) FROM nums
就知道了,因为您使用整数进行除法,所以它并不精确。
答案 1 :(得分:0)
您使用了错误的工具来解决问题。
如果要计算列表的方差,请使用某种脚本语言,例如Php,Python等。如果要首先存储,而仅然后计算差异,当然可以使用MySql之类的方法。
答案 2 :(得分:0)
我还认为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
查看正在运行的demo here。
方差可能要复杂得多,但我希望您能理解。